//+------------------------------------------------------------------+
//|                    智能对冲交易系统 V2.0                          |
//|                    Smart Trading Systems                          |
//|                    www.smarttrade.com                             |
//+------------------------------------------------------------------+
#property copyright "Smart Trading Systems"
#property link      "www.smarttrade.com"
#property version   "2.00"

//+------------------------------------------------------------------+
//| 订单注释说明                                                       |
//+------------------------------------------------------------------+
// "NN" - Normal Order (普通订单)
//        表示按照正常补仓逻辑创建的订单
//        适用于首单和常规补仓单
//
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| 输入参数（参考MQ4原策略）                                          |
//+------------------------------------------------------------------+
input string 阶段一参数 = "";       //-阶段一参数 参考MQ4原策略---------------
input int FirstStep = 20;                  // 首单距离
input int MinDistance = 60;                 // 最小距离(挂单间距)
input int StepTrallOrders = 5;              // 挂单追踪点数
input int Step = 50;                        // 补单间距(挂单触发)
input double lot = 0.01;                    // 起始手数
input double K_Lot = 1.2;                   // 倍率
input double StopProfit = 2;                // 单边平仓金额
input int MaxSpread = 100;                   // 点差限制
input int Magic = 9453;                     // 魔术码
input int ResetOrderCount = 4;               // 阶段一单方向最大持仓订单数

//+------------------------------------------------------------------+
//| 阶段二参数                                                        |
//+------------------------------------------------------------------+
input string 阶段二参数 = "";      //阶段二参数--------------------------------------
input int Phase2DistancePoints = 5;       // 阶段二升级距离条件（点）
input double Phase2InitialLot = 0.01;        // 阶段二首单手数
input double Phase2ProfitTarget = 3;       // 阶段二整体平仓盈利目标（美金）
input double Phase2SelectiveProfitTarget = 1; // 阶段二选择性平仓盈利目标（美金）
input int Phase2SelectiveCloseMaxStopLossCount = 8; // 阶段二选择性平仓最大止损单数（优化模式）
input bool EnableOptimalStopLossCalculation = true; // 启用最优止损单数计算
input double Phase2TrendMultiplier = 1.2;   // 阶段二顺势倍数
input double Phase2AntiMultiplier = 1.1;    // 阶段二逆势倍数
input int Phase2TrendDistance = 120;        // 阶段二顺势间距（点）
input int Phase2AntiDistance = 120;         // 阶段二逆势间距（点）
input double Phase2MaxSingleLot = 0.5;       // 阶段二单次最大手数
input double Phase2LotBalanceThreshold = 0.1; // 阶段二手数平衡阈值
input bool Phase2UseClosePrice = true;        // 阶段二使用收盘价判断加仓（false=使用实时价格）

//+------------------------------------------------------------------+
//| 均线显示参数                                                      |
//+------------------------------------------------------------------+
input string 均线显示参数 = "";     //均线显示参数--------------------------------------
input int MAPeriod = 20;                    // 均线周期
input int MAMethod = MODE_SMA;              // 均线类型 (0=SMA,1=EMA,2=SMMA,3=LWMA)
input bool EnableMADisplay = true;          // 启用均线显示
input bool ShowMAInPanel = true;            // 在监控面板显示均线信息
input bool ShowMATrendArrow = true;         // 显示趋势箭头
input color MALineColor = clrYellow;        // 均线颜色
input int MALineWidth = 2;                  // 均线宽度
input double MAAngleThreshold = 0.00001;    // 均线角度阈值（小于此值视为横盘）

// // 可用选项： 
// #define MODE_SMA     0  // 简单移动平均线 (Simple MA)
// #define MODE_EMA     1  // 指数移动平均线 (Exponential MA)
// #define MODE_SMMA    2  // 平滑移动平均线 (Smoothed MA)
// #define MODE_LWMA    3  // 线性加权移动平均线 (Linear Weighted MA)

//+------------------------------------------------------------------+
//| 监控面板参数                                                      |
//+------------------------------------------------------------------+
input string 监控面板参数 = "";     //监控面板参数--------------------------------------
input bool ShowMonitorPanel = true;          // 显示监控面板
input int PanelXOffset = 150;                 // 面板横向偏移量（正数向右移动）
input int PanelYOffset = 0;                 // 面板纵向偏移量（正数向下移动）

//+------------------------------------------------------------------+
//| 阶段三参数                                                        |
//+------------------------------------------------------------------+
input string 阶段三参数 = "";        // 阶段三参数-------------------------------------- 
input bool EnablePhaseThree = false;              // 启用阶段三（否则最高到阶段二）
input bool Phase3EnablePostCloseReset = true;    // 阶段三启用平仓后重置
input bool Phase3EnableReverseTrendReset = true; // 阶段三启用反向顺势重置

//+------------------------------------------------------------------+
//| 全局风控参数                                                      |
//+------------------------------------------------------------------+
input int levelRiskInput = 0;       // --------------------------全局风控参数--------------------------------------
input bool EnableGlobalRiskControl = true;        // 启用全局风控
input double MaxAccountLoss = 1000;                // 账户最大亏损金额（美金），超过则全平
input bool EnableAccountLossAlert = true;         // 启用账户亏损警报

//+------------------------------------------------------------------+
//| 全局变量                                                           |
//+------------------------------------------------------------------+
// 阶段管理
enum ENUM_PHASE
{
    PHASE_ONE = 1,    // 阶段一
    PHASE_TWO = 2,    // 阶段二
    PHASE_THREE = 3   // 阶段三
};

ENUM_PHASE currentPhase = PHASE_ONE;        // 当前运行阶段

// 系统状态
bool isPaused = false;                      // 暂停状态
datetime pauseEndTime = 0;                  // 暂停结束时间

// 有效期控制
bool EnableExpiryCheck = false;              // 启用有效期检查（内部变量） false 关闭
datetime ExpiryDate = D'2055.09.20 00:00'; // 策略有效期截止日期
bool isExpired = false;                     // 策略是否已过期


// 持仓统计
int buyPositions = 0;                       // 多头持仓数量
int sellPositions = 0;                      // 空头持仓数量
double buyLots = 0.0;                       // 多头总手数
double sellLots = 0.0;                      // 空头总手数
int buyOrderCount = 0;                      // 多头订单计数（用于手数计算）
int sellOrderCount = 0;                     // 空头订单计数（用于手数计算）
bool buylossthansell = false;               // 多头手数失衡（不使用）
bool sellllossthanbuy = false;              // 空头手数失衡（不使用）

// 价格统计
double minBuyPrice = 0.0;                   // 多头最低价格
double maxBuyPrice = 0.0;                   // 多头最高价格
double minSellPrice = 0.0;                  // 空头最低价格
double maxSellPrice = 0.0;                  // 空头最高价格

// 补仓计数器
int buyTrendCount = 0;                      // 多头顺势补仓次数
int buyAntiCount = 0;                       // 多头逆势补仓次数
int sellTrendCount = 0;                     // 空头顺势补仓次数
int sellAntiCount = 0;                      // 空头逆势补仓次数

// 【重要修复说明】关于buyOrderCount/sellOrderCount的使用
// 问题：挂单刚成交时，这些计数器可能存在同步延迟，导致错误判断首单/补单
// 解决：阶段一首单判断改用buyPositions/sellPositions（实时准确的持仓数据）
// 保留：buyOrderCount/sellOrderCount仍用于其他逻辑（如阶段升级条件等）

// 挂单追踪
int buyPendingTicket = 0;                   // 多头挂单票号
int sellPendingTicket = 0;                  // 空头挂单票号
double lastBuyPendingPrice = 0.0;           // 上次多头挂单价格
double lastSellPendingPrice = 0.0;          // 上次空头挂单价格

// 挂单成交检测
static int lastBuyPositionCount = 0;         // 上次买单持仓数
static int lastSellPositionCount = 0;        // 上次卖单持仓数

// 时间控制（参考MQ4逻辑）
datetime lastBuyTime = 0;                   // 上次多头开仓时间
datetime lastSellTime = 0;                  // 上次空头开仓时间

// 参数控制（参考MQ4原策略）
bool UseSetp = true;                        // 使用第一套参数（true）还是第二套参数（false）

// 总盈亏统计
double totalProfit = 0.0;                   // 总浮动盈亏
double buyProfit = 0.0;                     // 买单浮动盈亏
double sellProfit = 0.0;                    // 卖单浮动盈亏

// 总盈亏控制（参考MQ4原策略）
bool useFirstParams = true;                 // 使用第一套参数（true）还是第二套参数（false）

//+------------------------------------------------------------------+
//| 亏损单信息结构体
//+------------------------------------------------------------------+
struct LossPositionInfo
{
    ulong ticket;          // 持仓票号
    double lossPercent;    // 亏损百分比
    double lossAmount;     // 亏损金额
};

// 阶段二相关变量
int phase2BuyTrendCount = 0;                // 阶段二多头顺势补仓次数
int phase2BuyAntiCount = 0;                 // 阶段二多头逆势补仓次数  
int phase2SellTrendCount = 0;               // 阶段二空头顺势补仓次数
int phase2SellAntiCount = 0;                // 阶段二空头逆势补仓次数
double lastBuyPrice = 0.0;                  // 最后一次买入价格
double lastSellPrice = 0.0;                 // 最后一次卖出价格
double phase2TotalProfit = 0.0;             // 阶段二总盈亏
int maHandle = INVALID_HANDLE;              // 均线句柄

// 选择性平仓状态跟踪变量
bool selectiveCloseEnabled = false;         // 选择性平仓是否启用
string selectiveCloseStatus = "等待条件";    // 选择性平仓状态
string selectiveCloseCondition = "";        // 选择性平仓条件描述

// 持仓统计时间记录（原缓存机制已移除）
datetime lastPositionStatsUpdate = 0;      // 上次更新时间（仅用于记录）
bool positionStatsCacheValid = false;      // 【已废弃】原缓存标志，保留以防其他代码引用

// 预分配数组 - 避免频繁动态分配
LossPositionInfo globalLossPositions[200]; // 预分配最大200个亏损持仓
double globalCumulativeLoss[200];          // 预分配累积损失数组
double selectiveNetProfit = 0.0;            // 选择性平仓净盈利
datetime lastSelectiveCheck = 0;            // 上次选择性平仓检查时间

//+------------------------------------------------------------------+
//| 监控面板相关变量                                                  |
//+------------------------------------------------------------------+
bool showPanel = true;                      // 显示监控面板
int panelX = 20;                           // 面板X坐标
int panelY = 30;                           // 面板Y坐标
int panelWidth = 320;                      // 面板宽度
int panelHeight = 650;                     // 面板高度
color panelBgColor = C'25,25,75';         // 面板背景色（深蓝色）
color panelTextColor = clrAquamarine;      // 面板文字色（浅青色）
color panelBorderColor = clrGold;          // 面板边框色（金色）
color panelHeaderColor = C'35,35,95';      // 面板标题背景色
color panelProfitColor = clrLime;          // 盈利颜色
color panelLossColor = clrOrangeRed;       // 亏损颜色

// 均线角度显示相关变量
bool showMALine = true;                     // 显示均线
string maLineObjectName = "MA_Line";       // 均线对象名称
color maLineColor = clrYellow;              // 均线颜色
int maLineWidth = 1;                        // 均线宽度
double currentMAAngle = 0.0;                // 当前均线角度
double maAngleHistory[5] = {0.0};          // 均线角度历史（用于计算）
string angleCalculationDetails = "";        // 角度计算详情

//+------------------------------------------------------------------+
//| 获取支持的填充模式                                                |
//+------------------------------------------------------------------+
ENUM_ORDER_TYPE_FILLING GetSupportedFillingMode()
{
    long filling_mode = SymbolInfoInteger(Symbol(), SYMBOL_FILLING_MODE);
    
    if((filling_mode & SYMBOL_FILLING_IOC) != 0)
        return ORDER_FILLING_IOC;
    else if((filling_mode & SYMBOL_FILLING_FOK) != 0)
        return ORDER_FILLING_FOK;
    else
        return ORDER_FILLING_IOC; // 默认使用IOC
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // 检查策略有效期
    if(EnableExpiryCheck)
    {
        datetime currentTime = TimeCurrent();
        if(currentTime >= ExpiryDate)
        {
            isExpired = true;
            Print("系统已过期，当前时间: ", TimeToString(currentTime), ", 有效期截止: ", TimeToString(ExpiryDate));
            Alert("系统授权已过期，请联系客服更新");
            return(INIT_FAILED);
        }
        else
        {
            Print("系统有效期检查通过，有效期至: ", TimeToString(ExpiryDate));
        }
    }
    
    // 初始化全局变量
    isPaused = false;
    
    // 检查填充模式支持
    Print("经纪商支持的填充模式:");
    long filling_mode = SymbolInfoInteger(Symbol(), SYMBOL_FILLING_MODE);
    if((filling_mode & SYMBOL_FILLING_IOC) != 0)
        Print("- IOC (Immediate Or Cancel)");
    if((filling_mode & SYMBOL_FILLING_FOK) != 0)
        Print("- FOK (Fill Or Kill)");
    Print("使用填充模式: ", EnumToString(GetSupportedFillingMode()));
    
    // 获取并打印交易限制信息
    double minLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
    double maxLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX);
    double lotStep = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
    Print("交易限制 - 最小手数: ", minLot, ", 最大手数: ", maxLot, ", 手数步长: ", lotStep);
    
    // 更新持仓统计
    UpdatePositionStats();
    
    // 初始化订单计数（根据现有持仓）
    buyOrderCount = buyPositions;
    sellOrderCount = sellPositions;
    
    // 初始化最后开仓价格
    UpdateLastOpenPrice();
    
    // 恢复EA状态 - 根据现有持仓和挂单判断应该处于哪个阶段
    RecoverEAState();
    
    // 初始化均线指标
    maHandle = iMA(Symbol(), PERIOD_CURRENT, MAPeriod, 0, (ENUM_MA_METHOD)MAMethod, PRICE_CLOSE);
    if(maHandle == INVALID_HANDLE)
    {
        Print("均线指标初始化失败");
        return(INIT_FAILED);
    }
    
    // 检查是否应该直接进入阶段二
    if(ResetOrderCount == 0 && (buyPositions > 0 || sellPositions > 0))
    {
        currentPhase = PHASE_TWO;
        Print("ResetOrderCount=0 且存在持仓，直接进入阶段二");
        
        // 删除所有挂单
        DeleteAllPendingOrders();
        
        // 重置阶段二计数器
        ResetPhase2Counters();
    }
    
    // 初始化选择性平仓状态
    selectiveCloseEnabled = false;
    selectiveCloseStatus = "等待条件";
    selectiveCloseCondition = "";
    selectiveNetProfit = 0.0;
    lastSelectiveCheck = 0;
    
    // 初始化面板显示状态
    showPanel = ShowMonitorPanel;
    
    Print("=== 智能对冲交易系统 V2.0 初始化完成 ===");
    Print("当前阶段: ", EnumToString(currentPhase));
    Print("初始状态: buyPositions=", buyPositions, ", sellPositions=", sellPositions);
    Print("初始状态: buyOrderCount=", buyOrderCount, ", sellOrderCount=", sellOrderCount);
    Print("价格状态: minBuyPrice=", minBuyPrice, ", maxBuyPrice=", maxBuyPrice);
    Print("价格状态: minSellPrice=", minSellPrice, ", maxSellPrice=", maxSellPrice);
    Print("重置订单参数: ResetOrderCount=", ResetOrderCount, " (", ResetOrderCount > 0 ? "启用" : "禁用", ")");
    Print("全局风控状态: ", EnableGlobalRiskControl ? "启用" : "禁用", 
          ", 最大亏损阈值=", MaxAccountLoss, "美金, 警报功能=", EnableAccountLossAlert ? "启用" : "禁用");
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // 释放均线句柄
    if(maHandle != INVALID_HANDLE)
    {
        IndicatorRelease(maHandle);
    }
    
    // 清理监控面板
    DeletePanelObjects();
    
    // 清理均线对象 - 已删除
    // DeleteMALineObjects();
    
    Print("EA已停止运行");
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // 限制OnTick执行频率避免栈溢出 - 最多每秒执行一次主逻辑
    static datetime lastTickTime = 0;
    datetime currentTime = TimeCurrent();
    
    // 基础检查（始终执行）
    if(EnableExpiryCheck && !isExpired)
    {
        if(currentTime >= ExpiryDate)
        {
            isExpired = true;
            Print("系统已过期，停止执行交易逻辑");
            Alert("系统授权已过期，请联系客服更新");
            return;
        }
    }
    else if(isExpired)
    {
        return; // 策略已过期，不执行任何操作
    }
    
    // 检查暂停状态
    if(isPaused)
    {
        if(currentTime >= pauseEndTime)
        {
            isPaused = false;
            Print("暂停结束，恢复交易");
        }
        else
        {
            return; // 暂停期间不执行任何操作
        }
    }
    
    // 【修复】移除主逻辑频率限制，避免关键交易时机延迟
    // 原逻辑：每秒限制会导致挂单成交后1秒内无法及时响应
    // 修复：允许OnTick正常执行，仅对耗时操作单独限制频率
    // 注：MT5 OnTick本身就有合理的触发频率，无需额外限制
    
    // 更新持仓统计
    UpdatePositionStats();
    
    // 输出调试信息（降低频率）
    static int lastBuyPositions = 0;
    static int lastSellPositions = 0;
    static datetime lastDebugTime = 0;
    if((buyPositions != lastBuyPositions || sellPositions != lastSellPositions) && 
       currentTime - lastDebugTime >= 5) // 每5秒最多输出一次
    {
        Print("持仓变化: buyPositions=", buyPositions, ", sellPositions=", sellPositions, 
              ", currentPhase=", EnumToString(currentPhase), ", ResetOrderCount=", ResetOrderCount);
        lastBuyPositions = buyPositions;
        lastSellPositions = sellPositions;
        lastDebugTime = currentTime;
    }
    
    // 检查阶段升级条件
    if(currentPhase == PHASE_ONE)
    {
        CheckPhaseUpgrade();
    }
    
    // 根据当前阶段执行不同逻辑
    switch(currentPhase)
    {
        case PHASE_ONE:
            // 阶段一：挂单模式
            ManagePendingOrders();
            TrackAndModifyPendingOrders();
            break;
            
        case PHASE_TWO:
            // 阶段二：市价模式 + 循环盈利
            ManagePhase2Orders(); //管理订单，加仓逻辑
            CheckPhase2ProfitTarget(); // 检查利润目标是否达成  
            CheckLotBalance();
            break;
            
        case PHASE_THREE:
            // 阶段三：继续执行阶段二逻辑 + 参数重置
            ManagePhase2Orders();
            CheckPhase2ProfitTarget();
            CheckLotBalance(); 
            break;
    }
    
    // 风险控制检查
    CheckRiskControl();
    
    // 更新显示信息（降低频率）
    static datetime lastDisplayUpdate = 0;
    if(currentTime - lastDisplayUpdate >= 3) // 每3秒更新一次显示
    {
        UpdateDisplay();
        if(ShowMonitorPanel) // 根据参数控制是否显示面板
        {
            DrawMonitoringPanel();
        }
        lastDisplayUpdate = currentTime;
    }
}

//+------------------------------------------------------------------+
//| 管理挂单（参考MQ4原策略）                                         |
//+------------------------------------------------------------------+
void ManagePendingOrders()
{
    // 如果ResetOrderCount=0且有持仓，不应该继续管理挂单
    if(ResetOrderCount == 0 && (buyPositions > 0 || sellPositions > 0))
    {
        return;
    }
    
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    
    // 更新状态和盈亏
    UpdateTotalProfit();
    UpdateUseStepStatus();
    UpdateLossBalance();
    
    // 检查是否应该平仓
    if(CheckSingleSideProfit())
        return;
    
    // 管理买入挂单
    int buyStopCount = GetBuyStopCount();
    
    // 检查是否已达到ResetOrderCount，如果达到则不创建新挂单
    if(ResetOrderCount > 0 && buyOrderCount >= ResetOrderCount)
    {
        // 已达到上限，不创建新挂单
    }
    else if(buyStopCount == 0)
    {
        double price;
        double lots;
        
        // 【修复】使用实际持仓数量判断首单/补单，保持与CheckBuyPendingCondition一致
        if(buyPositions == 0)
        {
            // 首单逻辑：无买入持仓时创建首单
            price = NormalizeDouble(FirstStep * _Point + ask, _Digits);
            lots = lot;
        }
        else
        {
            // 补单逻辑：有买入持仓时创建补单
            if(minBuyPrice > 0)
            {
                // 抄底补单：价格设为最低持仓价-间距
                price = NormalizeDouble(minBuyPrice - MinDistance * _Point, _Digits);
            }
            else
            {
                // 备用逻辑：如果minBuyPrice异常为0，使用ask+间距
                price = NormalizeDouble(MinDistance * _Point + ask, _Digits);
            }
            
            // 补单手数递增：使用实际持仓数量计算倍率
            lots = NormalizeDouble(lot * MathPow(K_Lot, buyPositions), 2);
        }
        
        // 检查条件并创建挂单
        if(CheckBuyPendingCondition(price))
        {
            // 【修复后】只有满足条件时才输出详细信息，使用buyPositions显示持仓状态
            if(buyPositions == 0)
            {
                Print("[DEBUG] 买入首单: price=", price, " (", FirstStep, "点+ask), lots=", lots);
            }
            else
            {
                if(minBuyPrice > 0)
                {
                    Print("[DEBUG] 买入补单(抄底): price=", price, " (minBuyPrice=", minBuyPrice, " - ", MinDistance, "点), minBuyPrice状态=正常");
                }
                else
                {
                    Print("[DEBUG] 买入补单(备用): price=", price, " (ask+", MinDistance, "点), minBuyPrice状态=异常(0)");
                }
            }
            
            Print("准备检查买入挂单条件: 计算价格=", price, ", 手数=", lots, ", buyPositions=", buyPositions);
            Print("买入挂单条件满足，开始创建挂单...");
            CreateBuyPending(price, lots);
        }
    }
    
    // 管理卖出挂单
    int sellStopCount = GetSellStopCount();
    // Print("卖出挂单管理: sellStopCount=", sellStopCount, ", sellOrderCount=", sellOrderCount, ", ResetOrderCount=", ResetOrderCount);
    
    // 检查是否已达到ResetOrderCount，如果达到则不创建新挂单
    if(ResetOrderCount > 0 && sellOrderCount >= ResetOrderCount)
    {
        // 已达到上限，不创建新挂单
    }
    else if(sellStopCount == 0)
    {
        double price;
        double lots;
        
        // 【修复】使用实际持仓数量判断首单/补单，保持与CheckSellPendingCondition一致
        if(sellPositions == 0)
        {
            // 首单逻辑：无卖出持仓时创建首单
            price = NormalizeDouble(bid - FirstStep * _Point, _Digits);
            lots = lot;
        }
        else
        {
            // 补单逻辑：有卖出持仓时创建补单
            if(maxSellPrice > 0)
            {
                // 抄顶补单：价格设为最高持仓价+间距
                price = NormalizeDouble(maxSellPrice + MinDistance * _Point, _Digits);
            }
            else
            {
                // 备用逻辑：如果maxSellPrice异常为0，使用bid-间距
                price = NormalizeDouble(bid - MinDistance * _Point, _Digits);
            }
            
            // 补单手数递增：使用实际持仓数量计算倍率
            lots = NormalizeDouble(lot * MathPow(K_Lot, sellPositions), 2);
        }
        
        // 检查条件并创建挂单
   
        if(CheckSellPendingCondition(price))
        {
            Print("准备检查卖出挂单条件: 计算价格=", price, ", 手数=", lots, ", sellPositions=", sellPositions);
            Print("卖出挂单条件满足，开始创建挂单...");
            CreateSellPending(price, lots);
        }
        else
        {
            // Print("卖出挂单条件不满足，跳过创建");
        }
    }
}

//+------------------------------------------------------------------+
//| 更新总盈亏                                                        |
//+------------------------------------------------------------------+
void UpdateTotalProfit()
{
    totalProfit = 0.0;
    buyProfit = 0.0;
    sellProfit = 0.0;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                double profit = PositionGetDouble(POSITION_PROFIT) + 
                               PositionGetDouble(POSITION_SWAP);
                               
                totalProfit += profit;
                
                if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                    buyProfit += profit;
                else
                    sellProfit += profit;
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 更新UseSetp状态                                                   |
//+------------------------------------------------------------------+
void UpdateUseStepStatus()
{
    UseSetp = true;  // 始终使用第一套参数
}


//+------------------------------------------------------------------+
//| 检查单边平仓                                                      |
//+------------------------------------------------------------------+
bool CheckSingleSideProfit()
{
    if(buyProfit > StopProfit)
    {
        Print("=== 买单盈利触发平仓 ===");
        Print("触发条件：买单盈利 ", buyProfit, " > 目标盈利 ", StopProfit);
        Print("当前买单持仓数: ", buyPositions);
        ClosePositions(true);
        return true;
    }
    
    if(sellProfit > StopProfit)
    {
        Print("=== 卖单盈利触发平仓 ===");
        Print("触发条件：卖单盈利 ", sellProfit, " > 目标盈利 ", StopProfit);
        Print("当前卖单持仓数: ", sellPositions);
        ClosePositions(false);
        return true;
    }
    
    return false;
}

//+------------------------------------------------------------------+
//| 检查买入挂单条件                                                  |
//+------------------------------------------------------------------+
bool CheckBuyPendingCondition(double price)
{
    // 【修复】使用实际持仓数量判断是否为首单，避免buyOrderCount同步延迟问题
    // 问题：挂单刚成交时，buyOrderCount可能还是0，导致错误地认为是首单
    // 解决：直接使用buyPositions判断，这是MT5的实时权威数据
    if(buyPositions == 0)
    {
        Print("=== 买入首单触发 ===");
        Print("检测到首单条件（buyPositions=0），直接创建买入挂单");
        return true;  // 无买入持仓=首单，总是创建
    }
    
    // 抄底加仓逻辑：当ask < 多单最低价 - 50点时触发
    if(minBuyPrice != 0.0)
    {
        double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
        double triggerPrice = NormalizeDouble(minBuyPrice - Step * _Point, _Digits);
        bool result = ask < triggerPrice;
        
        if(result)
        {
            Print("=== 买入抄底加仓触发 ===");
            Print("触发条件满足：");
            Print("  多单最低价: ", minBuyPrice);
            Print("  Step参数: ", Step, "点");
            Print("  触发价格 = ", minBuyPrice, " - ", Step, "点 = ", triggerPrice);
            Print("  当前ASK: ", ask, " < ", triggerPrice, " (满足抄底条件)");
            Print("  挂单价格将设为: ",minBuyPrice,"-", MinDistance, "=", NormalizeDouble(minBuyPrice - MinDistance * _Point, _Digits));
        }
        
        return result;
    }
    
    return false;
}

//+------------------------------------------------------------------+
//| 检查卖出挂单条件                                                  |
//+------------------------------------------------------------------+
bool CheckSellPendingCondition(double price)
{
    // 【修复】使用实际持仓数量判断是否为首单，避免sellOrderCount同步延迟问题
    // 问题：挂单刚成交时，sellOrderCount可能还是0，导致错误地认为是首单
    // 解决：直接使用sellPositions判断，这是MT5的实时权威数据
    if(sellPositions == 0)
    {
        Print("=== 卖出首单触发 ===");
        Print("检测到首单条件（sellPositions=0），直接创建卖出挂单");
        return true;  // 无卖出持仓=首单，总是创建
    }
    
    // 抄顶加仓逻辑：当bid > 空单最高价 + 50点时触发
    if(maxSellPrice != 0.0)
    {
        double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
        double triggerPrice = NormalizeDouble(maxSellPrice + Step * _Point, _Digits);
        bool result = bid > triggerPrice;
        
        if(result)
        {
            Print("=== 卖出抄顶加仓触发 ===");
            Print("触发条件满足：");
            Print("  空单最高价: ", maxSellPrice);
            Print("  Step参数: ", Step, "点");
            Print("  触发价格 = ", maxSellPrice, " + ", Step, "点 = ", triggerPrice);
            Print("  当前BID: ", bid, " > ", triggerPrice, " (满足抄顶条件)");
            Print("  挂单价格将设为: ", maxSellPrice, "+", MinDistance, "=", NormalizeDouble(maxSellPrice + MinDistance * _Point, _Digits));
        }
        
        return result;
    }
    
    return false;
}

//+------------------------------------------------------------------+
//| 创建买入挂单                                                      |
//+------------------------------------------------------------------+
bool CreateBuyPending(double price, double lots)
{
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    // 纯逆向策略，统一使用NN注释
    string comment = "NN";
    
    request.action = TRADE_ACTION_PENDING;
    request.symbol = Symbol();
    request.volume = lots;
    request.type = ORDER_TYPE_BUY_STOP;
    request.price = price;
    request.deviation = 10;
    request.type_filling = GetSupportedFillingMode();
    request.comment = comment;
    request.magic = Magic;
    
    if(OrderSend(request, result))
    {
        buyPendingTicket = (int)result.order;
        lastBuyPendingPrice = price;
        Print("*** 买入挂单创建成功 *** 票号:", buyPendingTicket, ", 价格:", price, ", 手数:", lots);
        return true;
    }
    
    Print("买入挂单创建失败: ", result.retcode, ", ", result.comment);
    return false;
}

//+------------------------------------------------------------------+
//| 创建卖出挂单                                                      |
//+------------------------------------------------------------------+
bool CreateSellPending(double price, double lots)
{
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    // 纯逆向策略，统一使用NN注释
    string comment = "NN";
    
    request.action = TRADE_ACTION_PENDING;
    request.symbol = Symbol();
    request.volume = lots;
    request.type = ORDER_TYPE_SELL_STOP;
    request.price = price;
    request.deviation = 10;
    request.type_filling = GetSupportedFillingMode();
    request.comment = comment;
    request.magic = Magic;
    
    if(OrderSend(request, result))
    {
        sellPendingTicket = (int)result.order;
        lastSellPendingPrice = price;
        Print("*** 卖出挂单创建成功 *** 票号:", sellPendingTicket, ", 价格:", price, ", 手数:", lots);
        return true;
    }
    
    Print("卖出挂单创建失败: ", result.retcode, ", ", result.comment);
    return false;
}

//+------------------------------------------------------------------+
//| 追踪和修改挂单（参考MQ4原策略）                                  |
//+------------------------------------------------------------------+
void TrackAndModifyPendingOrders()
{
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    
    // 更新状态
    UpdateTotalProfit();
    UpdateUseStepStatus();
    UpdateLossBalance();
    
    // 修改买入挂单
    if(buyPendingTicket > 0)
    {
        double buyStopPrice = GetPendingOrderPrice(buyPendingTicket);
        if(buyStopPrice > 0)
        {
            // 计算新价格（与创建时相同的逻辑）
            double price;
            if(buyOrderCount == 0)
            {
                price = NormalizeDouble(FirstStep * _Point + ask, _Digits);
            }
            else
            {
                price = NormalizeDouble(MinDistance * _Point + ask, _Digits);
                    
                if(minBuyPrice > 0)
                {
                    if(price < NormalizeDouble(minBuyPrice - Step * _Point, _Digits))
                        price = NormalizeDouble(Step * _Point + ask, _Digits);
                }
            }
            
            // 参考MQ4条件：第1035行
            if(NormalizeDouble(buyStopPrice - StepTrallOrders * _Point, _Digits) > price)
            {
                // MQ4中这里也有复杂的条件判断，但我们简化为基本价格条件
                bool canModify = true;
                
                canModify = (price <= NormalizeDouble(minBuyPrice - Step * _Point, _Digits) || minBuyPrice == 0.0 ||
                            price >= NormalizeDouble(Step * _Point + minBuyPrice, _Digits));
                
                if(canModify)
                {
                    ModifyPendingOrder(buyPendingTicket, price);
                }
            }
        }
        else
        {
            // 挂单不存在，清除票号
            buyPendingTicket = 0;
        }
    }
    
    // 修改卖出挂单
    if(sellPendingTicket > 0)
    {
        double sellStopPrice = GetPendingOrderPrice(sellPendingTicket);
        if(sellStopPrice > 0)
        {
            // 计算新价格
            double price;
            if(sellOrderCount == 0)
            {
                price = NormalizeDouble(bid - FirstStep * _Point, _Digits);
            }
            else
            {
                price = NormalizeDouble(bid - MinDistance * _Point, _Digits);
                    
                if(maxSellPrice > 0)
                {
                    if(price > NormalizeDouble(maxSellPrice + Step * _Point, _Digits))
                        price = NormalizeDouble(bid - Step * _Point, _Digits);
                }
            }
            
            // 参考MQ4条件：第1069行
            if(NormalizeDouble(StepTrallOrders * _Point + sellStopPrice, _Digits) < price)
            {
                // MQ4中这里也有复杂的条件判断，但我们简化为基本价格条件
                bool canModify = true;
                
                canModify = (price >= NormalizeDouble(maxSellPrice + Step * _Point, _Digits) || maxSellPrice == 0.0 ||
                            price <= NormalizeDouble(maxSellPrice - Step * _Point, _Digits));
                
                if(canModify)
                {
                    ModifyPendingOrder(sellPendingTicket, price);
                }
            }
        }
        else
        {
            // 挂单不存在，清除票号
            sellPendingTicket = 0;
        }
    }
}

//+------------------------------------------------------------------+
//| 获取挂单价格                                                      |
//+------------------------------------------------------------------+
double GetPendingOrderPrice(int ticket)
{
    for(int i = 0; i < OrdersTotal(); i++)
    {
        ulong orderTicket = OrderGetTicket(i);
        if(orderTicket == ticket)
        {
            if(OrderSelect(orderTicket))
            {
                return OrderGetDouble(ORDER_PRICE_OPEN);
            }
        }
    }
    return 0;
}

//+------------------------------------------------------------------+
//| 修改挂单                                                          |
//+------------------------------------------------------------------+
bool ModifyPendingOrder(int ticket, double newPrice)
{
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    request.action = TRADE_ACTION_MODIFY;
    request.order = ticket;
    request.price = newPrice;
    
    if(OrderSend(request, result))
    {
        // 更新对应的挂单价格记录，避免重复修改
        if(ticket == buyPendingTicket)
            lastBuyPendingPrice = newPrice;
        else if(ticket == sellPendingTicket)  
            lastSellPendingPrice = newPrice;
            
        // Print("挂单修改成功: 票号 ", ticket, " 新价格: ", newPrice);
        return true;
    }
    
    Print("挂单修改失败: ", result.retcode);
    return false;
}

//+------------------------------------------------------------------+
//| 获取买入挂单数量                                                  |
//+------------------------------------------------------------------+
int GetBuyStopCount()
{
    int count = 0;
    for(int i = 0; i < OrdersTotal(); i++)
    {
        ulong orderTicket = OrderGetTicket(i);
        if(OrderSelect(orderTicket))
        {
            if(OrderGetString(ORDER_SYMBOL) == Symbol() && 
               OrderGetInteger(ORDER_MAGIC) == Magic &&
               OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP)
            {
                count++;
            }
        }
    }
    return count;
}

//+------------------------------------------------------------------+
//| 获取卖出挂单数量                                                  |
//+------------------------------------------------------------------+
int GetSellStopCount()
{
    int count = 0;
    for(int i = 0; i < OrdersTotal(); i++)
    {
        ulong orderTicket = OrderGetTicket(i);
        if(OrderSelect(orderTicket))
        {
            if(OrderGetString(ORDER_SYMBOL) == Symbol() && 
               OrderGetInteger(ORDER_MAGIC) == Magic &&
               OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP)
            {
                count++;
            }
        }
    }
    return count;
}







//+------------------------------------------------------------------+
//| 持仓统计更新                                                      |
//+------------------------------------------------------------------+
void UpdatePositionStats(bool foreUpdate=false)
{
    // 【修复】移除缓存机制，确保持仓统计实时准确
    // 原问题：缓存延迟导致buyOrderCount更新滞后，引发首单误判
    // 修复：每次调用都实时更新，确保交易决策基于最新数据
    // 性能考虑：持仓统计计算很轻量，实时更新不会有明显性能影响
    
    datetime currentTime = TimeCurrent();
    
    buyPositions = 0;
    sellPositions = 0;
    buyLots = 0.0;
    sellLots = 0.0;
    minBuyPrice = 0.0;
    maxBuyPrice = 0.0;
    minSellPrice = 0.0;
    maxSellPrice = 0.0;
    
    // 重置补仓计数器
    buyTrendCount = 0;
    buyAntiCount = 0;
    sellTrendCount = 0;
    sellAntiCount = 0;
    
    // 统计订单数量（参考MQ4逻辑）
    int buyStopCount = 0;
    int sellStopCount = 0;
    
    // 检查挂单
    for(int i = 0; i < OrdersTotal(); i++)
    {
        ulong orderTicket = OrderGetTicket(i);
        if(OrderSelect(orderTicket))
        {
            if(OrderGetString(ORDER_SYMBOL) == Symbol() && 
               OrderGetInteger(ORDER_MAGIC) == Magic)
            {
                ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
                
                if(orderType == ORDER_TYPE_BUY_STOP)
                {
                    buyStopCount++;
                    // 跟踪票号
                    if(buyPendingTicket == 0 || buyPendingTicket == orderTicket)
                    {
                        buyPendingTicket = (int)orderTicket;
                    }
                }
                else if(orderType == ORDER_TYPE_SELL_STOP)
                {
                    sellStopCount++;
                    // 跟踪票号
                    if(sellPendingTicket == 0 || sellPendingTicket == orderTicket)
                    {
                        sellPendingTicket = (int)orderTicket;
                    }
                }
            }
        }
    }
    
    // 如果挂单不存在，清除票号
    if(buyStopCount == 0) buyPendingTicket = 0;
    if(sellStopCount == 0) sellPendingTicket = 0;
    
    // 统计持仓
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                double volume = PositionGetDouble(POSITION_VOLUME);
                string comment = PositionGetString(POSITION_COMMENT);
                
                if(posType == POSITION_TYPE_BUY)
                {
                    buyPositions++;
                    buyLots += volume;
                    
                    if(minBuyPrice == 0.0 || openPrice < minBuyPrice)
                        minBuyPrice = openPrice;
                    if(maxBuyPrice == 0.0 || openPrice > maxBuyPrice)
                        maxBuyPrice = openPrice;
                }
                else if(posType == POSITION_TYPE_SELL)
                {
                    sellPositions++;
                    sellLots += volume;
                    
                    if(minSellPrice == 0.0 || openPrice < minSellPrice)
                        minSellPrice = openPrice;
                    if(maxSellPrice == 0.0 || openPrice > maxSellPrice)
                        maxSellPrice = openPrice;
                }
            }
        }
    }
    
    // 计算订单计数（用于手数计算）
    // 参考MQ4：所有持仓都计入
    buyOrderCount = buyPositions;
    sellOrderCount = sellPositions;
    
    // 只在持仓发生变化时输出关键信息
    static int lastLoggedBuyPositions = -1;
    static int lastLoggedSellPositions = -1;
    static double lastLoggedMinBuyPrice = -1;
    
    if(buyPositions != lastLoggedBuyPositions || sellPositions != lastLoggedSellPositions || 
       (minBuyPrice > 0 && minBuyPrice != lastLoggedMinBuyPrice))
    {
        Print("[DEBUG] 持仓变化: 买单=", buyPositions, ", 卖单=", sellPositions, 
              ", minBuyPrice=", minBuyPrice, ", maxBuyPrice=", maxBuyPrice);
        lastLoggedBuyPositions = buyPositions;
        lastLoggedSellPositions = sellPositions;
        lastLoggedMinBuyPrice = minBuyPrice;
    }
    
    // 【修复】移除缓存状态维护，确保每次调用都实时更新
    // 注：保留lastPositionStatsUpdate用于其他可能的逻辑，但不再用于缓存控制
    lastPositionStatsUpdate = currentTime;
    
    // 输出调试信息（降低频率）
    static datetime lastStatsDebugTime = 0;
    if(currentTime - lastStatsDebugTime >= 10) // 每10秒最多输出一次
    {
        // Print("持仓统计更新: 买单=", buyPositions, ", 卖单=", sellPositions, 
            //   ", 买手数=", DoubleToString(buyLots, 2), ", 卖手数=", DoubleToString(sellLots, 2));
        lastStatsDebugTime = currentTime;
    }
}

//+------------------------------------------------------------------+
//| 删除所有挂单                                                      |
//+------------------------------------------------------------------+
void DeleteAllPendingOrders()
{
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    int deletedCount = 0;
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        if(OrderSelect(OrderGetTicket(i)))
        {
            if(OrderGetString(ORDER_SYMBOL) == Symbol())
            {
                ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
                if(orderType == ORDER_TYPE_BUY_STOP || orderType == ORDER_TYPE_SELL_STOP)
                {
                    request.action = TRADE_ACTION_REMOVE;
                    request.order = OrderGetTicket(i);
                    
                    if(OrderSend(request, result))
                    {
                        deletedCount++;
                        Print("删除挂单成功: ", OrderGetTicket(i));
                    }
                    else
                    {
                        Print("删除挂单失败（DeleteAll）: ", result.retcode, ", ", result.comment);
                    }
                }
            }
        }
    }
    Print("删除挂单总数: ", deletedCount);
}

//+------------------------------------------------------------------+
//| 平掉指定方向持仓                                                  |
//+------------------------------------------------------------------+
void ClosePositions(bool closeBuy)
{
    Print("=== 阶段一平仓操作开始 ===");
    Print("平仓方向: ", (closeBuy ? "平买单" : "平卖单"));
    Print("当前总持仓数: ", PositionsTotal());
    Print("当前买单盈利: ", buyProfit);
    Print("当前卖单盈利: ", sellProfit);
    
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    int closedCount = 0;
    double totalClosedVolume = 0;
    
    // 先平仓
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                
                if((closeBuy && posType == POSITION_TYPE_BUY) || 
                   (!closeBuy && posType == POSITION_TYPE_SELL))
                {
                    ulong ticket = PositionGetTicket(i);
                    double volume = PositionGetDouble(POSITION_VOLUME);
                    double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                    double currentPrice = (posType == POSITION_TYPE_BUY) ? 
                                         SymbolInfoDouble(Symbol(), SYMBOL_BID) : 
                                         SymbolInfoDouble(Symbol(), SYMBOL_ASK);
                    double positionProfit = PositionGetDouble(POSITION_PROFIT);
                    
                    Print("平仓详情:");
                    Print("  票号: ", ticket);
                    Print("  类型: ", (posType == POSITION_TYPE_BUY ? "买单" : "卖单"));
                    Print("  手数: ", volume);
                    Print("  开仓价: ", openPrice);
                    Print("  平仓价: ", currentPrice);
                    Print("  单仓盈亏: ", positionProfit);
                    
                    request.action = TRADE_ACTION_DEAL;
                    request.symbol = Symbol();
                    request.volume = volume;
                    request.type = (posType == POSITION_TYPE_BUY) ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
                    request.price = currentPrice;
                    request.deviation = 10;
                    request.position = ticket;
                    request.type_filling = GetSupportedFillingMode();
                    request.magic = Magic;
                    
                    if(!OrderSend(request, result))
                    {
                        Print("  *** 平仓失败 *** 错误码: ", result.retcode, ", 描述: ", result.comment);
                    }
                    else
                    {
                        Print("  *** 平仓成功 *** 票号: ", ticket);
                        closedCount++;
                        totalClosedVolume += volume;
                    }
                }
            }
        }
    }
    
    Print("=== 平仓操作总结 ===");
    Print("平仓数量: ", closedCount, "个位置");
    Print("平仓总手数: ", totalClosedVolume);
    
    
    // 删除对应挂单
    Print("开始删除对应挂单...");
    int canceledOrders = 0;
    
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        ulong orderTicket = OrderGetTicket(i);
        if(OrderSelect(orderTicket))
        {
            if(OrderGetString(ORDER_SYMBOL) == Symbol() && 
               OrderGetInteger(ORDER_MAGIC) == Magic)
            {
                ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
                
                if((closeBuy && orderType == ORDER_TYPE_BUY_STOP) || 
                   (!closeBuy && orderType == ORDER_TYPE_SELL_STOP))
                {
                    request.action = TRADE_ACTION_REMOVE;
                    request.order = orderTicket;
                    
                    if(!OrderSend(request, result))
                    {
                        Print("删除挂单失败: ", result.retcode, ", ", result.comment);
                    }
                    else
                    {
                        Print("删除挂单成功: 票号=", orderTicket);
                    }
                }
            }
        }
    }
    
    // 重置计数器
    if(closeBuy)
    {
        buyOrderCount = 0;
        buyPendingTicket = 0;
    }
    else
    {
        sellOrderCount = 0;
        sellPendingTicket = 0;
    }
    
    // 需要检查 当前是否还有持仓 没有持仓就需要回到阶段一的逻辑 修改状态回到阶段一 
    //有持仓再走原来逻辑 
    // 删除所有挂单
    DeleteAllPendingOrders();
    // 平仓完成后，更新持仓统计
    UpdatePositionStats(true);

    // 检查是否还有持仓
    if(buyPositions == 0 && sellPositions == 0)
    {
        // 完全无持仓，回到阶段一
        Print("单方向平仓后无任何持仓，回到阶段一");
        currentPhase = PHASE_ONE;
        return; // 不开立新的阶段二首单
    }else{
        Print("单方向平仓后还有持仓，继续阶段二 买单:", buyPositions, " 卖单:", sellPositions);
    }


    // 如果在阶段二或阶段三，单方向平仓后需要立即开新首单
    if(currentPhase == PHASE_TWO || currentPhase == PHASE_THREE)
    {
        Print("阶段二/三：", (closeBuy ? "买单" : "卖单"), "平仓完成，重置所有补仓计数器");
        
        // 立即开立对应方向的新首单
        MqlTradeRequest request = {};
        MqlTradeResult result = {};
        
        double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
        double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
        
        request.action = TRADE_ACTION_DEAL;
        request.symbol = Symbol();
        request.volume = Phase2InitialLot;
        request.deviation = 10;
        request.type_filling = GetSupportedFillingMode();
        request.magic = Magic;
        
        if(closeBuy)
        {
            // 平了买单，开新买单
            request.type = ORDER_TYPE_BUY;
            request.price = ask;
            request.comment = "阶段2_多头首单";
            
            if(OrderSend(request, result))
            {
                Print("单方向平仓后开立新买单成功: 价格=", ask, ", 手数=", Phase2InitialLot);
                lastBuyPrice = ask;
                lastBuyTime = TimeCurrent();
                // 更新阶段二买入计数器：首单开完，顺势和逆势计数器都从0变为1
                phase2BuyTrendCount = 1;
                phase2BuyAntiCount = 1;
                Print("单方向平仓后买单计数器更新: phase2BuyTrendCount = ", phase2BuyTrendCount, ", phase2BuyAntiCount = ", phase2BuyAntiCount);
            }
            else
            {
                Print("单方向平仓后开立新买单失败: ", result.retcode, ", ", result.comment);
            }
        }
        else
        {
            // 平了卖单，开新卖单
            request.type = ORDER_TYPE_SELL;
            request.price = bid;
            request.comment = "阶段2_空头首单";
            
            if(OrderSend(request, result))
            {
                Print("单方向平仓后开立新卖单成功: 价格=", bid, ", 手数=", Phase2InitialLot);
                lastSellPrice = bid;
                lastSellTime = TimeCurrent();
                // 更新阶段二卖出计数器：首单开完，顺势和逆势计数器都从0变为1
                phase2SellTrendCount = 1;
                phase2SellAntiCount = 1;
                Print("单方向平仓后卖单计数器更新: phase2SellTrendCount = ", phase2SellTrendCount, ", phase2SellAntiCount = ", phase2SellAntiCount);
            }
            else
            {
                Print("单方向平仓后开立新卖单失败: ", result.retcode, ", ", result.comment);
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 风险控制检查                                                      |
//+------------------------------------------------------------------+
void CheckRiskControl()
{
    // 检查点差
    double spread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);
    if(spread > MaxSpread)
    {
        Print("当前点差过大: ", spread, "，暂停交易");
        return;
    }
    
    // 检查全局风控
    if(EnableGlobalRiskControl)
    {
        CheckGlobalAccountLoss();
    }
}

//+------------------------------------------------------------------+
//| 检查全局账户亏损风控                                              |
//+------------------------------------------------------------------+
void CheckGlobalAccountLoss()
{
    // 计算账户总浮动盈亏
    double accountTotalProfit = 0.0;
    int totalPositions = 0;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                double profit = PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
                accountTotalProfit += profit;
                totalPositions++;
            }
        }
    }
    
    // 账户亏损警报
    if(EnableAccountLossAlert && accountTotalProfit < -MaxAccountLoss * 0.8)
    {
        // 当亏损达到80%阈值时发出警报，每分钟最多一次
        static datetime lastAlertTime = 0;
        if(TimeCurrent() - lastAlertTime >= 60)
        {
            Print("【风控警报】账户亏损接近阈值: 当前亏损=", DoubleToString(-accountTotalProfit, 2), 
                  "美金, 阈值=", MaxAccountLoss, "美金, 持仓数=", totalPositions);
            lastAlertTime = TimeCurrent();
        }
    }
    
    // 检查是否超过最大亏损阈值
    if(accountTotalProfit <= -MaxAccountLoss)
    {
        Print("【风控触发】账户亏损超过阈值，执行全平操作!");
        Print("当前账户总亏损: ", DoubleToString(-accountTotalProfit, 2), "美金");
        Print("设定的最大亏损阈值: ", MaxAccountLoss, "美金");
        Print("当前持仓数量: ", totalPositions);
        
        // 执行紧急全平
        ExecuteEmergencyCloseAll();
        
        // 暂停EA运行10分钟
        isPaused = true;
        pauseEndTime = TimeCurrent() + 600;  // 10分钟后恢复
        Print("EA已暂停运行10分钟，暂停结束时间: ", TimeToString(pauseEndTime));
    }
}

//+------------------------------------------------------------------+
//| 紧急全平所有持仓                                                  |
//+------------------------------------------------------------------+
void ExecuteEmergencyCloseAll()
{
    Print("开始执行紧急全平操作...");
    
    // 删除所有挂单
    DeleteAllPendingOrders();
    
    // 平掉所有持仓
    CloseAllPositions();
    
    // 重置所有状态
    currentPhase = PHASE_ONE;
    buyOrderCount = 0;
    sellOrderCount = 0;
    ResetPhase2Counters();
    
    Print("紧急全平操作完成，所有状态已重置");
}

//+------------------------------------------------------------------+
//| 平掉所有持仓                                                      |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol())
            {
                request.action = TRADE_ACTION_DEAL;
                request.symbol = Symbol();
                request.volume = PositionGetDouble(POSITION_VOLUME);
                request.type = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? 
                              ORDER_TYPE_SELL : ORDER_TYPE_BUY;
                request.price = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? 
                               SymbolInfoDouble(Symbol(), SYMBOL_BID) : 
                               SymbolInfoDouble(Symbol(), SYMBOL_ASK);
                request.deviation = 10;
                request.position = PositionGetTicket(i);
                request.type_filling = GetSupportedFillingMode();
                request.magic = Magic;
                
                if(!OrderSend(request, result))
                {
                    Print("全部平仓失败: ", result.retcode, ", ", result.comment);
                }
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 统一重置阶段二/三计数器                                           |
//+------------------------------------------------------------------+
void ResetPhase2Counters()
{
    // 重置阶段二/三的所有计数器
    phase2BuyTrendCount = 0;
    phase2BuyAntiCount = 0;
    phase2SellTrendCount = 0;
    phase2SellAntiCount = 0;
    
    Print("阶段二/三计数器已重置: 所有顺势和逆势补仓次数清零");
}

//+------------------------------------------------------------------+
//| 阶段三平仓后重置                                                  |
//+------------------------------------------------------------------+
void Phase3PostCloseReset()
{
    if(currentPhase != PHASE_THREE)
        return;
    
    if(!Phase3EnablePostCloseReset)
        return;
    
    // 使用统一重置函数
    ResetPhase2Counters();
    Print("阶段三: 执行平仓后重置完成");
}

//+------------------------------------------------------------------+
//| 阶段三反向顺势重置（优化版：统一重置所有计数器）                    |
//+------------------------------------------------------------------+
void Phase3ReverseTrendReset(bool isBuyClose)
{
    // 不再限制只在阶段三执行，阶段二和阶段三都需要重置
    if(currentPhase != PHASE_TWO && currentPhase != PHASE_THREE)
        return;
    
    // 选择性平仓后统一重置所有计数器，确保干净的状态
    ResetPhase2Counters();
    
    // 计算MA角度用于日志输出
    double maAngle = CalculateMAAngle();
    Print("选择性平仓后重置: 平仓方向=", (isBuyClose ? "多头" : "空头"), 
          ", 趋势角度=", DoubleToString(maAngle, 5), 
          ", 当前阶段=", EnumToString(currentPhase));
}

//+------------------------------------------------------------------+
//| 更新显示信息                                                      |
//+------------------------------------------------------------------+
void UpdateDisplay()
{
    // 计算总盈亏
    double totalProfit = 0.0;
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol())
            {
                totalProfit += PositionGetDouble(POSITION_PROFIT) + 
                              PositionGetDouble(POSITION_SWAP);
            }
        }
    }
    
    // 在图表上显示信息
    string phaseStr = "";
    switch(currentPhase)
    {
        case PHASE_ONE: phaseStr = "阶段一"; break;
        case PHASE_TWO: phaseStr = "阶段二"; break;
        case PHASE_THREE: phaseStr = "阶段三"; break;
    }
    
    string phaseDisplay = "";
    switch(currentPhase)
    {
        case PHASE_ONE: phaseDisplay = "智能建仓"; break;
        case PHASE_TWO: phaseDisplay = "动态对冲"; break;
        case PHASE_THREE: phaseDisplay = "高级风控"; break;
    }
    
    string info = StringFormat(
        "智能对冲系统 V2.0 | %s | 多头: %d单(%.2f手) | 空头: %d单(%.2f手) | 盈亏: %.2f",
        phaseDisplay, buyPositions, buyLots, sellPositions, sellLots, totalProfit
    );
    
    Comment(info);
}

//+------------------------------------------------------------------+
//| 更新手数失衡状态（保留函数但不使用）                              |
//+------------------------------------------------------------------+
void UpdateLossBalance()
{
    // 本函数原用于计算手数失衡，现不使用手数失衡判断
    // 保留空函数以避免修改过多代码
}

//+------------------------------------------------------------------+
//| 检查阶段升级条件                                                  |
//+------------------------------------------------------------------+
void CheckPhaseUpgrade()
{
    if(currentPhase != PHASE_ONE)
        return;
    
    // 当ResetOrderCount=0时，不使用补仓次数作为升级条件
    if(ResetOrderCount == 0)
    {
        // 只检查是否有持仓
        if(buyPositions > 0 || sellPositions > 0)
        {
            Print("ResetOrderCount=0，检测到持仓，直接升级到阶段二");
            Print("当前持仓: buyPositions=", buyPositions, ", sellPositions=", sellPositions);
            currentPhase = PHASE_TWO;
            
            // 删除所有挂单
            DeleteAllPendingOrders();
            
            // 重置阶段二计数器
            phase2BuyTrendCount = 0;
            phase2BuyAntiCount = 0;
            phase2SellTrendCount = 0;
            phase2SellAntiCount = 0;
            
            // 立即执行阶段二开仓
            ExecutePhase2InitialOrders();
        }
        else
        {
            Print("ResetOrderCount=0，但没有持仓，保持在阶段一");
        }
        return;
    }
    
    // ResetOrderCount > 0 时的原有逻辑
    bool countCondition = false;
    if(buyOrderCount >= ResetOrderCount || sellOrderCount >= ResetOrderCount)
    {
        countCondition = true;
    }
    
    // 条件2：价格距离条件（默认200点）
    bool distanceCondition = false;
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    
    // 记录最后开仓价格
    UpdateLastOpenPrice();
    
    // 调试信息只在价格有更新时输出
    static double lastDebugBuyPrice = 0;
    static double lastDebugSellPrice = 0;
    if(lastBuyPrice != lastDebugBuyPrice || lastSellPrice != lastDebugSellPrice)
    {
        Print("更新后的价格: lastBuyPrice=", lastBuyPrice, ", lastSellPrice=", lastSellPrice);
        lastDebugBuyPrice = lastBuyPrice;
        lastDebugSellPrice = lastSellPrice;
    }
    
    if(buyOrderCount >= ResetOrderCount && lastBuyPrice > 0)
    {
        double distance = MathAbs((bid - lastBuyPrice) / _Point);
        if(distance>Phase2DistancePoints)
        {
            distanceCondition = true;
            Print("多头距离检查: bid - lastBuyPrice = abs（", distance, "）点, 需要>=", Phase2DistancePoints, "点");
            Print("多头触发升级条件: bid=", bid, ", lastBuyPrice=", lastBuyPrice, 
                  ", 距离=", distance, "点"); 
        }
    }
    
    if(sellOrderCount >= ResetOrderCount && lastSellPrice > 0)
    {
        double distance = MathAbs((lastSellPrice - ask) / _Point);
        if(distance > Phase2DistancePoints)
        {
            distanceCondition = true;
            Print("空头距离检查: lastSellPrice - ask = abs（", distance, "）点, 需要>=", Phase2DistancePoints, "点");
            Print("空头触发升级条件: ask=", ask, ", lastSellPrice=", lastSellPrice,
                  ", 距离=", distance, "点");
        }
    }
    
    // 输出调试信息只在满足升级条件时
    if(countCondition && distanceCondition)
    {
        Print("升级条件检查: countCondition=", countCondition, 
              ", distanceCondition=", distanceCondition,
              ", buyOrderCount=", buyOrderCount, ", sellOrderCount=", sellOrderCount);
    }
    
    // 两个条件都满足时升级到阶段二
    if(countCondition && distanceCondition)
    {
        Print("满足升级条件，从阶段一升级到阶段二");
        currentPhase = PHASE_TWO;
        
        // 删除所有挂单
        DeleteAllPendingOrders();
        Print("从阶段一升级到阶段二 删除所有挂单 完成");
        Print("从阶段一升级到阶段二 重置阶段二计数器 开始");
        // 重置阶段二计数器
        ResetPhase2Counters();
        Print("从阶段一升级到阶段二 重置阶段二计数器 完成");
        Print("从阶段一升级到阶段二 立即执行阶段二开仓");
        // 立即执行阶段二开仓
        ExecutePhase2InitialOrders();
    }
}

//+------------------------------------------------------------------+
//| 更新最后开仓价格                                                  |
//+------------------------------------------------------------------+
void UpdateLastOpenPrice()
{
    // 临时变量存储找到的最新价格和时间
    double tempLastBuyPrice = 0;
    double tempLastSellPrice = 0;
    datetime tempLastBuyTime = 0;
    datetime tempLastSellTime = 0;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                datetime openTime = (datetime)PositionGetInteger(POSITION_TIME);
                
                if(posType == POSITION_TYPE_BUY)
                {
                    if(openTime > tempLastBuyTime)
                    {
                        tempLastBuyPrice = openPrice;
                        tempLastBuyTime = openTime;
                    }
                }
                else if(posType == POSITION_TYPE_SELL)
                {
                    if(openTime > tempLastSellTime)
                    {
                        tempLastSellPrice = openPrice;
                        tempLastSellTime = openTime;
                    }
                }
            }
        }
    }
    
    // 只在找到有效价格时更新
    if(tempLastBuyTime > 0)
    {
        lastBuyPrice = tempLastBuyPrice;
        lastBuyTime = tempLastBuyTime;
    }
    if(tempLastSellTime > 0)
    {
        lastSellPrice = tempLastSellPrice;
        lastSellTime = tempLastSellTime;
    }
}

//+------------------------------------------------------------------+
//| 执行阶段二初始开仓                                               |
//+------------------------------------------------------------------+
void ExecutePhase2InitialOrders()
{
    Print("\n========== 执行阶段二初始开仓 ==========");
    Print("当前阶段: ", EnumToString(currentPhase));
    
    // 立即开立多空首单
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    
    // 开多单
    request.action = TRADE_ACTION_DEAL;
    request.symbol = Symbol();
    request.volume = Phase2InitialLot;
    request.type = ORDER_TYPE_BUY;
    request.price = ask;
    request.deviation = 10;
    request.type_filling = GetSupportedFillingMode();
    request.comment = "阶段2_多头首单";
    request.magic = Magic;
    
    if(OrderSend(request, result))
    {
        Print("阶段二多头首单开仓成功: 价格=", ask, ", 手数=", Phase2InitialLot);
        // 更新最后买入价格
        lastBuyPrice = ask;
        lastBuyTime = TimeCurrent();
        // 更新阶段二买入计数器：首单开完，顺势和逆势计数器都从0变为1
        phase2BuyTrendCount = 1;
        phase2BuyAntiCount = 1;
        Print("阶段二多头首单计数器更新: phase2BuyTrendCount = ", phase2BuyTrendCount, ", phase2BuyAntiCount = ", phase2BuyAntiCount);
    }
    else
    {
        Print("阶段二多头首单开仓失败: ", result.retcode, ", ", result.comment);
    }
    
    // 开空单
    request.type = ORDER_TYPE_SELL;
    request.price = bid;
    request.comment = "阶段2_空头首单";
    
    if(OrderSend(request, result))
    {
        Print("阶段二空头首单开仓成功: 价格=", bid, ", 手数=", Phase2InitialLot);
        // 更新最后卖出价格
        lastSellPrice = bid;
        lastSellTime = TimeCurrent();
        // 更新阶段二卖出计数器：首单开完，顺势和逆势计数器都从0变为1
        phase2SellTrendCount = 1;
        phase2SellAntiCount = 1;
        Print("阶段二空头首单计数器更新: phase2SellTrendCount = ", phase2SellTrendCount, ", phase2SellAntiCount = ", phase2SellAntiCount);
    }
    else
    {
        Print("阶段二空头首单开仓失败: ", result.retcode, ", ", result.comment);
    }
    
    // 检查手数平衡
    CheckLotBalance();
    
    Print("========== 阶段二初始开仓完成 ==========\n");
}

//+------------------------------------------------------------------+
//| 管理阶段二订单                                                    |
//+------------------------------------------------------------------+
void ManagePhase2Orders()
{
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    
    // 更新阶段二持仓统计
    UpdatePhase2Stats();
    
    // 检查是否需要加仓
    CheckPhase2AddPosition();
}

//+------------------------------------------------------------------+
//| 更新阶段二统计信息                                               |
//+------------------------------------------------------------------+
void UpdatePhase2Stats()
{
    // 统计阶段二的持仓
    int phase2BuyCount = 0;
    int phase2SellCount = 0;
    double phase2BuyLots = 0;
    double phase2SellLots = 0;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                string comment = PositionGetString(POSITION_COMMENT);
                
                // 检查是否是阶段二的订单
                if(StringFind(comment, "阶段2_") >= 0 || StringFind(comment, "阶段3_") >= 0)
                {
                    ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                    double volume = PositionGetDouble(POSITION_VOLUME);
                    
                    if(posType == POSITION_TYPE_BUY)
                    {
                        phase2BuyCount++;
                        phase2BuyLots += volume;
                    }
                    else
                    {
                        phase2SellCount++;
                        phase2SellLots += volume;
                    }
                }
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 检查阶段二加仓条件                                               |
//+------------------------------------------------------------------+
void CheckPhase2AddPosition()
{
    // 获取当前实时价格
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    
    // 用于判断的价格变量
    double buyTrendCheckPrice;  // 多头顺势判断价格
    double buyAntiCheckPrice;   // 多头逆势判断价格
    double sellTrendCheckPrice; // 空头顺势判断价格
    double sellAntiCheckPrice;  // 空头逆势判断价格
    
    // 防止重复触发的时间记录
    datetime currentBarTime = iTime(Symbol(), PERIOD_CURRENT, 0);
    static datetime lastBuyTrendBarTime = 0;
    static datetime lastBuyAntiBarTime = 0;
    static datetime lastSellTrendBarTime = 0;
    static datetime lastSellAntiBarTime = 0;
    
    if(Phase2UseClosePrice)
    {
        // 模式1：使用上一根K线的收盘价判断
        double lastClose = iClose(Symbol(), PERIOD_CURRENT, 1);
        
        // 确保有有效的收盘价数据
        if(lastClose <= 0)
        {
            Print("无法获取上一根K线收盘价，跳过加仓检查");
            return;
        }
        
        // 确保至少有2根K线的数据
        if(iBars(Symbol(), PERIOD_CURRENT) < 2)
        {
            Print("K线数据不足，等待更多数据...");
            return;
        }
        
        // 使用收盘价作为所有判断价格
        buyTrendCheckPrice = lastClose;
        buyAntiCheckPrice = lastClose;
        sellTrendCheckPrice = lastClose;
        sellAntiCheckPrice = lastClose;
    }
    else
    {
        // 模式2：使用实时价格判断（原逻辑）
        buyTrendCheckPrice = bid;   // 多头顺势用bid
        buyAntiCheckPrice = ask;    // 多头逆势用ask
        sellTrendCheckPrice = ask;  // 空头顺势用ask
        sellAntiCheckPrice = bid;   // 空头逆势用bid
    }
    
    // 获取最新价格信息
    UpdateLastOpenPrice();
    
    // 更新持仓统计，确保有最新的价格范围
    UpdatePositionStats();
    
    // 检查多头加仓
    if(buyPositions > 0 && maxBuyPrice > 0 && minBuyPrice > 0)
    {
        // 顺势加仓：价格突破多头持仓最高价（向上突破）
        if(buyTrendCheckPrice > maxBuyPrice + Phase2TrendDistance * _Point)
        {
            // 使用收盘价模式时检查是否在当前K线已经执行过
            if(!Phase2UseClosePrice || lastBuyTrendBarTime < currentBarTime)
            {
                if(Phase2UseClosePrice)
                {
                    Print("阶段二多头顺势加仓条件满足: 上根收盘=", buyTrendCheckPrice, " > 最大买价", maxBuyPrice, " + 间距", Phase2TrendDistance * _Point);
                    Print("当前实时买价=", ask, " 卖价=", bid);
                }
                else
                {
                    Print("阶段二多头顺势加仓条件满足: 当前价格=", buyTrendCheckPrice, " > 最大买价", maxBuyPrice, " + 间距", Phase2TrendDistance * _Point);
                }
                double lots = CalculatePhase2Lots(true, true);
                OpenPhase2Position(true, lots, true);
                if(Phase2UseClosePrice) lastBuyTrendBarTime = currentBarTime;  // 记录执行时间
            }
        }
        // 逆势加仓：价格跌破多头持仓最低价
        else if(buyAntiCheckPrice < minBuyPrice - Phase2AntiDistance * _Point)
        {
            // 使用收盘价模式时检查是否在当前K线已经执行过
            if(!Phase2UseClosePrice || lastBuyAntiBarTime < currentBarTime)
            {
                if(Phase2UseClosePrice)
                {
                    Print("阶段二多头逆势加仓条件满足: 上根收盘=", buyAntiCheckPrice, " < 最小买价", minBuyPrice, " - 间距", Phase2AntiDistance * _Point);
                    Print("当前实时买价=", ask, " 卖价=", bid);
                }
                else
                {
                    Print("阶段二多头逆势加仓条件满足: 当前价格=", buyAntiCheckPrice, " < 最小买价", minBuyPrice, " - 间距", Phase2AntiDistance * _Point);
                }
                double lots = CalculatePhase2Lots(true, false);
                OpenPhase2Position(true, lots, false);
                if(Phase2UseClosePrice) lastBuyAntiBarTime = currentBarTime;  // 记录执行时间
            }
        }
    }
    
    // 检查空头加仓
    if(sellPositions > 0 && maxSellPrice > 0 && minSellPrice > 0)
    {
        // 顺势加仓：价格跌破空头持仓最低价（向下突破）
        if(sellTrendCheckPrice < minSellPrice - Phase2TrendDistance * _Point)
        {
            // 使用收盘价模式时检查是否在当前K线已经执行过
            if(!Phase2UseClosePrice || lastSellTrendBarTime < currentBarTime)
            {
                if(Phase2UseClosePrice)
                {
                    Print("阶段二空头顺势加仓条件满足: 上根收盘=", sellTrendCheckPrice, " < 最小卖价", minSellPrice, " - 间距", Phase2TrendDistance * _Point);
                    Print("当前实时买价=", ask, " 卖价=", bid);
                }
                else
                {
                    Print("阶段二空头顺势加仓条件满足: 当前价格=", sellTrendCheckPrice, " < 最小卖价", minSellPrice, " - 间距", Phase2TrendDistance * _Point);
                }
                double lots = CalculatePhase2Lots(false, true);
                OpenPhase2Position(false, lots, true);
                if(Phase2UseClosePrice) lastSellTrendBarTime = currentBarTime;  // 记录执行时间
            }
        }
        // 逆势加仓：价格突破空头持仓最高价
        else if(sellAntiCheckPrice > maxSellPrice + Phase2AntiDistance * _Point)
        {
            // 使用收盘价模式时检查是否在当前K线已经执行过
            if(!Phase2UseClosePrice || lastSellAntiBarTime < currentBarTime)
            {
                if(Phase2UseClosePrice)
                {
                    Print("阶段二空头逆势加仓条件满足: 上根收盘=", sellAntiCheckPrice, " > 最大卖价", maxSellPrice, " + 间距", Phase2AntiDistance * _Point);
                    Print("当前实时买价=", ask, " 卖价=", bid);
                }
                else
                {
                    Print("阶段二空头逆势加仓条件满足: 当前价格=", sellAntiCheckPrice, " > 最大卖价", maxSellPrice, " + 间距", Phase2AntiDistance * _Point);
                }
                double lots = CalculatePhase2Lots(false, false);
                OpenPhase2Position(false, lots, false);
                if(Phase2UseClosePrice) lastSellAntiBarTime = currentBarTime;  // 记录执行时间
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 计算阶段二手数                                                    |
//+------------------------------------------------------------------+
double CalculatePhase2Lots(bool isBuy, bool isTrend)
{
    double lots = Phase2InitialLot;
    int count = 0;
    double multiplier = 0;
    
    if(isBuy)
    {
        count = isTrend ? phase2BuyTrendCount : phase2BuyAntiCount;
    }
    else
    {
        count = isTrend ? phase2SellTrendCount : phase2SellAntiCount;
    }
    
    // 阶段二不使用ResetOrderCount重置机制，只计算正常倍数
    multiplier = isTrend ? Phase2TrendMultiplier : Phase2AntiMultiplier;
    
    // 计算手数
    lots = Phase2InitialLot * MathPow(multiplier, count);
    
    // 限制最大手数
    if(lots > Phase2MaxSingleLot)
    {
        lots = Phase2MaxSingleLot;
    }
    
    return NormalizeDouble(lots, 2);
}

//+------------------------------------------------------------------+
//| 开立阶段二仓位                                                    |
//+------------------------------------------------------------------+
void OpenPhase2Position(bool isBuy, double lots, bool isTrend)
{
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    double price = isBuy ? SymbolInfoDouble(Symbol(), SYMBOL_ASK) : SymbolInfoDouble(Symbol(), SYMBOL_BID);
    
    // 构建注释
    string phaseStr = (currentPhase == PHASE_TWO) ? "阶段2_" : "阶段3_";
    string dirStr = isBuy ? "多头" : "空头";
    string typeStr = "";
    int count = 0;
    
    // 获取当前计数器值（计数器语义：0=等待首单，1=已开首单，2=已开首单+补仓1...）
    if(isBuy)
    {
        count = isTrend ? phase2BuyTrendCount : phase2BuyAntiCount;
    }
    else
    {
        count = isTrend ? phase2SellTrendCount : phase2SellAntiCount;
    }
    
    // 根据计数器值构建注释
    if(count == 0)
    {
        typeStr = "首单";  // 等待开首单状态 → 开首单
    }
    else
    {
        typeStr = (isTrend ? "顺势" : "逆势") + IntegerToString(count);  // 补仓1,2,3...
    }
    
    string comment = phaseStr + dirStr + typeStr;
    
    request.action = TRADE_ACTION_DEAL;
    request.symbol = Symbol();
    request.volume = lots;
    request.type = isBuy ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
    request.price = price;
    request.deviation = 10;
    request.type_filling = GetSupportedFillingMode();
    request.comment = comment;
    request.magic = Magic;
    
    if(OrderSend(request, result))
    {
        Print(comment, " 开仓成功: 价格=", price, ", 手数=", lots);
        
        // 更新计数器
        if(isBuy)
        {
            if(isTrend) phase2BuyTrendCount++;
            else phase2BuyAntiCount++;
            // 更新最后买入价格
            lastBuyPrice = price;
            lastBuyTime = TimeCurrent();
        }
        else
        {
            if(isTrend) phase2SellTrendCount++;
            else phase2SellAntiCount++;
            // 更新最后卖出价格
            lastSellPrice = price;
            lastSellTime = TimeCurrent();
        }
        
        // 【修复】移除缓存失效逻辑，直接调用实时更新
        UpdatePositionStats();
    }
    else
    {
        Print(comment, " 开仓失败: ", result.retcode, ", ", result.comment);
    }
}

//+------------------------------------------------------------------+
//| 检查阶段二盈利目标                                               |
//+------------------------------------------------------------------+
void CheckPhase2ProfitTarget()
{
    // 计算阶段二总盈亏
    phase2TotalProfit = 0;
    double phase2BuyProfit = 0;
    double phase2SellProfit = 0;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                string comment = PositionGetString(POSITION_COMMENT);
                
                // 统计所有持仓盈亏（阶段二考虑全部持仓）
                double profit = PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
                phase2TotalProfit += profit;
                
                if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                    phase2BuyProfit += profit;
                else
                    phase2SellProfit += profit;
            }
        }
    }
    
    // 检查是否达到盈利目标
    if(phase2TotalProfit >= Phase2ProfitTarget)
    {
        Print("阶段二达到盈利目标: ", phase2TotalProfit);
        
        // 执行整体平仓
        ExecutePhase2CloseAll();
    }
    else
    {
        // 检查选择性平仓条件（不再依赖总盈利，而是检查盈亏分化）
        bool hasProfitLossSplit = (phase2BuyProfit > 0 && phase2SellProfit < 0) || (phase2SellProfit > 0 && phase2BuyProfit < 0);
        
        if(hasProfitLossSplit)
        {
            // Print("=== 检测到盈亏分化，检查选择性平仓条件 ===");
            // Print("phase2BuyProfit=", phase2BuyProfit, ", phase2SellProfit=", phase2SellProfit);
            // Print("phase2TotalProfit=", phase2TotalProfit, " (仅供参考，不作为触发条件)");
            CheckSelectiveClose(phase2BuyProfit, phase2SellProfit);
        }
        else
        {
            // 没有盈亏分化，重置状态
            selectiveCloseEnabled = false;
            if(phase2BuyProfit >= 0 && phase2SellProfit >= 0)
            {
                selectiveCloseStatus = "双向盈利";
                selectiveCloseCondition = StringFormat("买单盈利%.2f, 卖单盈利%.2f", phase2BuyProfit, phase2SellProfit);
            }
            else if(phase2BuyProfit <= 0 && phase2SellProfit <= 0)
            {
                selectiveCloseStatus = "双向亏损";
                selectiveCloseCondition = StringFormat("买单亏损%.2f, 卖单亏损%.2f", phase2BuyProfit, phase2SellProfit);
            }
            else
            {
                selectiveCloseStatus = "无明显分化";
                selectiveCloseCondition = StringFormat("买单%.2f, 卖单%.2f", phase2BuyProfit, phase2SellProfit);
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 执行阶段二整体平仓                                               |
//+------------------------------------------------------------------+
void ExecutePhase2CloseAll()
{
    Print("执行阶段二整体平仓");
    
    // 平掉所有持仓
    CloseAllPositions();
    
    // 删除所有挂单
    DeleteAllPendingOrders();
    
    if(currentPhase == PHASE_TWO)
    {
        if(EnablePhaseThree)
        {
            // 升级到阶段三
            currentPhase = PHASE_THREE;
            
            // 重置计数器
            ResetPhase2Counters();
            
            Print("升级到阶段三");
            
            // 立即开启新一轮
            ExecutePhase2InitialOrders();
        }
        else
        {
            // 重置到阶段一
            currentPhase = PHASE_ONE;
            
            // 重置所有计数器
            buyOrderCount = 0;
            sellOrderCount = 0;
            ResetPhase2Counters();
            
            Print("返回阶段一");
        }
    }
    else if(currentPhase == PHASE_THREE)
    {
        // 阶段三：保持在阶段三，但重置计数器
        phase2BuyTrendCount = 0;
        phase2BuyAntiCount = 0;
        phase2SellTrendCount = 0;
        phase2SellAntiCount = 0;
        
        Print("阶段三循环重置");
        
        // 执行阶段三平仓后重置
        Phase3PostCloseReset();
        
        // 立即开启新一轮
        ExecutePhase2InitialOrders();
    }
}

//+------------------------------------------------------------------+
//| 检查选择性平仓条件（优化版）                                      |
//+------------------------------------------------------------------+
void CheckSelectiveClose(double buyProfit, double sellProfit)
{
    // Print("========== 选择性平仓检查开始（优化版）==========");
    lastSelectiveCheck = TimeCurrent();
    
    // 基础统计信息
    int buyCount = 0, sellCount = 0, buyLossCount = 0, sellLossCount = 0;
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                double profit = PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
                if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                {
                    buyCount++;
                    if(profit < 0) buyLossCount++;
                }
                else
                {
                    sellCount++;
                    if(profit < 0) sellLossCount++;
                }
            }
        }
    }
    
    // Print("持仓统计: 买单", buyCount, "个(亏损", buyLossCount, "个), 卖单", sellCount, "个(亏损", sellLossCount, "个)");
    
    // 计算均线角度
    double maAngle = CalculateMAAngle();
    // Print("均线角度=", DoubleToString(maAngle, 5), " (>0上涨, <0下跌)");
    
    // 重置状态
    selectiveCloseEnabled = false;
    selectiveCloseStatus = "不满足条件";
    selectiveCloseCondition = "";
    selectiveNetProfit = 0.0;
    
    string calculationDetails = "";
    
    // 场景1：多头盈利，空头亏损，趋势向下
    if(buyProfit > 0 && sellProfit < 0 && maAngle < 0)
    {
        // Print("=== 多头盈利场景检测 ===");
        // Print("买单盈利=", DoubleToString(buyProfit, 2), ", 卖单亏损=", DoubleToString(sellProfit, 2), ", 趋势向下");
        
        if(EnableOptimalStopLossCalculation)
        {
            // 限制选择性平仓计算频率 - 每1秒最多执行一次
            static datetime lastSelectiveCalcTime = 0;
            if(TimeCurrent() - lastSelectiveCalcTime >= 1) //预留多订单平仓时间
            {
                lastSelectiveCalcTime = TimeCurrent();
                
                int optimalCount = CalculateOptimalStopLossCount(true, buyProfit, calculationDetails);
                
                if(optimalCount > 0)
                {
                    // 重新精确计算用于确认
                    double confirmStopLoss = CalculateStopLossAmount(false, optimalCount);
                    double confirmNetProfit = buyProfit - MathAbs(confirmStopLoss);
                    
                    selectiveCloseEnabled = true;
                    selectiveCloseStatus = "执行平仓";
                    selectiveCloseCondition = StringFormat("多头盈利%.2f, 优化止损%d单, 净盈利%.2f", 
                                                          buyProfit, optimalCount, confirmNetProfit);
                    selectiveNetProfit = confirmNetProfit;
                    
                    Print("*** 选择性平仓条件满足 ***");
                    Print("最优止损单数: ", optimalCount);
                    Print("确认净盈利: ", DoubleToString(confirmNetProfit, 2));
                    
                    ExecuteOptimalSelectiveClose(true, optimalCount, calculationDetails);
                }
                else
                {
                    selectiveCloseStatus = "净盈利不足";
                    selectiveCloseCondition = StringFormat("多头盈利%.2f, %s", buyProfit, calculationDetails);
                }
            }
            else
            {
                selectiveCloseStatus = "计算冷却中";
                selectiveCloseCondition = "等待计算间隔";
            }
        }
        else
        {
            // 使用原有固定逻辑
            double stopLoss = CalculateStopLossAmount(false, Phase2SelectiveCloseMaxStopLossCount);
            double netProfit = buyProfit - MathAbs(stopLoss);
            
            if(netProfit >= Phase2SelectiveProfitTarget)
            {
                selectiveCloseEnabled = true;
                selectiveCloseStatus = "执行平仓(固定)";
                ExecuteSelectiveClose(true);
            }
            else
            {
                selectiveCloseStatus = StringFormat("净盈利不足(%.2f<%.2f)", netProfit, Phase2SelectiveProfitTarget);
            }
        }
    }
    // 场景2：空头盈利，多头亏损，趋势向上
    else if(sellProfit > 0 && buyProfit < 0 && maAngle > 0)
    {
        // Print("=== 空头盈利场景检测 ===");
        // Print("卖单盈利=", DoubleToString(sellProfit, 2), ", 买单亏损=", DoubleToString(buyProfit, 2), ", 趋势向上");
        
        if(EnableOptimalStopLossCalculation)
        {
            // 限制选择性平仓计算频率 - 每30秒最多执行一次
            static datetime lastSelectiveCalcTime2 = 0;
            if(TimeCurrent() - lastSelectiveCalcTime2 >= 10)
            {
                lastSelectiveCalcTime2 = TimeCurrent();
                
                int optimalCount = CalculateOptimalStopLossCount(false, sellProfit, calculationDetails);
                
                if(optimalCount > 0)
                {
                    double confirmStopLoss = CalculateStopLossAmount(true, optimalCount);
                    double confirmNetProfit = sellProfit - MathAbs(confirmStopLoss);
                    
                    selectiveCloseEnabled = true;
                    selectiveCloseStatus = "执行平仓";
                    selectiveCloseCondition = StringFormat("空头盈利%.2f, 优化止损%d单, 净盈利%.2f", 
                                                          sellProfit, optimalCount, confirmNetProfit);
                    selectiveNetProfit = confirmNetProfit;
                    
                    Print("*** 选择性平仓条件满足 ***");
                    ExecuteOptimalSelectiveClose(false, optimalCount, calculationDetails);
                }
                else
                {
                    selectiveCloseStatus = "净盈利不足";
                    selectiveCloseCondition = StringFormat("空头盈利%.2f, %s", sellProfit, calculationDetails);
                }
            }
            else
            {
                selectiveCloseStatus = "计算冷却中";
                selectiveCloseCondition = "等待计算间隔";
            }
        }
        else
        {
            // 使用原有固定逻辑 选择固定订单数量止损模式   
            double stopLoss = CalculateStopLossAmount(true, Phase2SelectiveCloseMaxStopLossCount);
            double netProfit = sellProfit - MathAbs(stopLoss);
            
            if(netProfit >= Phase2SelectiveProfitTarget)
            {
                selectiveCloseEnabled = true;
                selectiveCloseStatus = "执行平仓(固定)";
                ExecuteSelectiveClose(false);
            }
            else
            {
                selectiveCloseStatus = StringFormat("净盈利不足(%.2f<%.2f)", netProfit, Phase2SelectiveProfitTarget);
            }
        }
    }
    // 其他情况
    else
    {
        if(buyProfit > 0 && sellProfit < 0 && !(maAngle < 0))
        {
            selectiveCloseStatus = "趋势不符(需向下)";
            selectiveCloseCondition = StringFormat("多头盈利%.2f但趋势不向下(角度%.5f)", buyProfit, maAngle);
        }
        else if(sellProfit > 0 && buyProfit < 0 && !(maAngle > 0))
        {
            selectiveCloseStatus = "趋势不符(需向上)";  
            selectiveCloseCondition = StringFormat("空头盈利%.2f但趋势不向上(角度%.5f)", sellProfit, maAngle);
        }
        else
        {
            selectiveCloseStatus = "无盈亏分化";
            selectiveCloseCondition = StringFormat("买单%.2f, 卖单%.2f", buyProfit, sellProfit);
        }
    }
    
    // Print("选择性平仓状态: ", selectiveCloseStatus);
    // Print("========== 选择性平仓检查完成 ==========");
}

//+------------------------------------------------------------------+
//| 计算需要止损的仓位亏损金额                                        |
//+------------------------------------------------------------------+
double CalculateStopLossAmount(bool isBuyDirection, int stopLossCount)
{
    Print("=== CalculateStopLossAmount ===");
    Print("isBuyDirection=", isBuyDirection, ", stopLossCount=", stopLossCount);
    
    LossPositionInfo lossPositions[];
    int lossCount = 0;
    
    // 统计亏损单数量
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                
                // 检查指定方向的亏损仓位
                if((isBuyDirection && posType == POSITION_TYPE_BUY) ||
                   (!isBuyDirection && posType == POSITION_TYPE_SELL))
                {
                    double profit = PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
                    Print("检查仓位: 票号=", PositionGetTicket(i), ", 类型=", posType == POSITION_TYPE_BUY ? "BUY" : "SELL", ", 盈亏=", profit);
                    if(profit < 0)  // 只统计亏损单
                    {
                        lossCount++;
                        Print("找到亏损单: 票号=", PositionGetTicket(i), ", 亏损=", profit);
                    }
                }
            }
        }
    }
    
    if(lossCount == 0)
        return 0.0;
    
    // 收集亏损单信息（预留更大空间防止数组越界）
    ArrayResize(lossPositions, lossCount + 5);  // 额外预留5个位置
    int index = 0;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                
                if((isBuyDirection && posType == POSITION_TYPE_BUY) ||
                   (!isBuyDirection && posType == POSITION_TYPE_SELL))
                {
                    double profit = PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
                    if(profit < 0)
                    {
                        // 添加数组越界保护
                        if(index >= ArraySize(lossPositions))
                        {
                            Print("警告: 数组空间不足，动态扩展数组大小");
                            ArrayResize(lossPositions, index + 10);
                        }
                        
                        double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                        double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
                        
                        // 计算亏损比例（添加除零保护）
                        double lossPercent = 0;
                        if(openPrice > 0)  // 防止除零错误
                        {
                            if(posType == POSITION_TYPE_BUY)
                            {
                                lossPercent = (currentPrice - openPrice) / openPrice * 100;
                            }
                            else
                            {
                                lossPercent = (openPrice - currentPrice) / openPrice * 100;
                            }
                        }
                        else
                        {
                            Print("警告: 开仓价格为0，跳过此仓位");
                            continue;
                        }
                        
                        lossPositions[index].ticket = PositionGetTicket(i);
                        lossPositions[index].lossPercent = lossPercent;
                        lossPositions[index].lossAmount = profit;
                        Print("收集亏损仓位[", index, "]: 票号=", PositionGetTicket(i), ", 亏损比例=", lossPercent, "%, 亏损金额=", profit);
                        index++;
                    }
                }
            }
        }
    }
    
    // 排序，最大亏损在前
    Print("排序前亏损仓位:");
    for(int i = 0; i < index; i++)
    {
        Print("  [", i, "] 票号=", lossPositions[i].ticket, ", 亏损比例=", lossPositions[i].lossPercent, "%, 亏损金额=", lossPositions[i].lossAmount);
    }
    
    SortLossPositions(lossPositions, index);
    
    Print("排序后亏损仓位:");
    for(int i = 0; i < index; i++)
    {
        Print("  [", i, "] 票号=", lossPositions[i].ticket, ", 亏损比例=", lossPositions[i].lossPercent, "%, 亏损金额=", lossPositions[i].lossAmount);
    }
    
    // 计算前N个最大亏损比例的总金额
    double totalStopLossAmount = 0.0;
    int actualStopCount = MathMin(stopLossCount, index);
    
    Print("计算前", actualStopCount, "个亏损比例最大的仓位:");
    for(int i = 0; i < actualStopCount; i++)
    {
        totalStopLossAmount += lossPositions[i].lossAmount;  // 已经是负值
        Print("  选择票号=", lossPositions[i].ticket, ", 亏损比例=", lossPositions[i].lossPercent, "%, 亏损金额=", lossPositions[i].lossAmount);
    }
    
    Print("前", actualStopCount, "个最大亏损比例仓位的总亏损金额=", totalStopLossAmount);
    
    return totalStopLossAmount;  // 返回负值，调用处需要用MathAbs()取绝对值
}

//+------------------------------------------------------------------+
//| 计算基于亏损比例的最优止损单数（核心优化函数）                    |
//+------------------------------------------------------------------+
int CalculateOptimalStopLossCount(bool isCloseBuy, double profitAmount, string &calculationDetails)
{
    // Print("========== 计算最优止损单数 ==========");
    // Print("方向: ", (isCloseBuy ? "平多头获利，止损空头" : "平空头获利，止损多头"));
    // Print("盈利金额: ", DoubleToString(profitAmount, 2));
    
    // 使用预分配数组收集亏损单信息 - 避免动态分配
    int lossCount = 0;
    const int maxLossPositions = 1000; // 最大亏损持仓数量限制
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                double profit = PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
                
                // 确定目标亏损方向
                bool isTargetDirection = (!isCloseBuy && posType == POSITION_TYPE_BUY) || 
                                       (isCloseBuy && posType == POSITION_TYPE_SELL);
                
                if(isTargetDirection && profit < 0)
                {
                    // 检查数组边界
                    if(lossCount >= maxLossPositions)
                    {
                        Print("警告: 亏损持仓数量超过最大限制", maxLossPositions, "，跳过后续持仓");
                        break;
                    }
                    
                    // 计算亏损比例（添加除零保护）
                    double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                    double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
                    double lossPercent = 0;
                    
                    if(openPrice > 0)  // 防止除零错误
                    {
                        if(posType == POSITION_TYPE_BUY)
                            lossPercent = (currentPrice - openPrice) / openPrice * 100;
                        else
                            lossPercent = (openPrice - currentPrice) / openPrice * 100;
                    }
                    else
                    {
                        Print("警告: CalculateOptimalStopLossCount开仓价格为0，跳过此仓位");
                        continue;
                    }
                    
                    // 使用预分配数组 - 无需动态分配
                    globalLossPositions[lossCount].ticket = PositionGetTicket(i);
                    globalLossPositions[lossCount].lossPercent = lossPercent;
                    globalLossPositions[lossCount].lossAmount = profit;  // 负值
                    lossCount++;
                    
                    // Print("收集亏损单[", lossCount-1, "]: 票号=", PositionGetTicket(i), 
                    //       ", 亏损比例=", DoubleToString(lossPercent, 2), "%, 亏损金额=", DoubleToString(profit, 2));
                }
            }
        }
    }
    
    if(lossCount == 0)
    {
        calculationDetails = "无亏损单可止损";
        // Print("未找到亏损单");
        return 0;
    }
    
    // 按亏损比例排序（最负的在前）- 使用预分配数组
    SortLossPositionsOptimized(lossCount);
    
    // Print("========== 排序后的亏损单（按亏损比例从大到小）==========");
    for(int i = 0; i < lossCount; i++)
    {
        // Print("[", i, "] 亏损比例=", DoubleToString(globalLossPositions[i].lossPercent, 2), 
        //       "%, 亏损金额=", DoubleToString(globalLossPositions[i].lossAmount, 2));
    }
    
    // 优化的最优止损计算 - 使用累积求和避免O(n²)复杂度
    int maxAllowed = MathMin(Phase2SelectiveCloseMaxStopLossCount, lossCount);
    // Print("最大允许止损: ", maxAllowed, ", 实际亏损单数: ", lossCount);
    
    // 使用预分配累积损失数组 - O(n)复杂度
    globalCumulativeLoss[0] = 0;
    
    for(int i = 1; i <= maxAllowed; i++)
    {
        globalCumulativeLoss[i] = globalCumulativeLoss[i-1] + MathAbs(globalLossPositions[i-1].lossAmount);
    }
    
    string calculationProcess = "";
    // 现在是O(n)复杂度而不是O(n²)
    for(int n = maxAllowed; n >= 1; n--)
    {
        double totalStopLoss = globalCumulativeLoss[n];  // O(1)查表而不是O(n)循环
        double netProfit = profitAmount - totalStopLoss;
        calculationProcess += StringFormat("N=%d:净%.2f ", n, netProfit);
        
        // Print("N=", n, ": 净盈利=", DoubleToString(netProfit, 2), " vs 目标=", Phase2SelectiveProfitTarget);
        
        if(netProfit >= Phase2SelectiveProfitTarget)
        {
            calculationDetails = StringFormat("最优N=%d, 净盈利=%.2f, 止损范围=%.2f%%~%.2f%%", 
                                            n, netProfit, globalLossPositions[n-1].lossPercent, globalLossPositions[0].lossPercent);
            // Print("*** 找到最优解: N=", n, ", 净盈利=", DoubleToString(netProfit, 2), " ***");
            return n;
        }
    }
    
    // calculationDetails = "无满足条件的方案: " + calculationProcess;
    // Print("未找到满足条件的止损方案");
    return 0;
}

//+------------------------------------------------------------------+
//| 计算均线角度                                                      |
//+------------------------------------------------------------------+
double CalculateMAAngle()
{
    // 限制计算频率避免栈溢出 - 每5秒最多计算一次
    static datetime lastCalculateTime = 0;
    static double lastCalculatedAngle = 0;
    
    datetime currentTime = TimeCurrent();
    if(currentTime - lastCalculateTime < 5)
    {
        return lastCalculatedAngle; // 返回缓存值
    }
    
    // 获取足够的历史数据，与指标保持一致
    int barsNeeded = 10;  // 多获取一些数据确保稳定
    double ma[];
    if(CopyBuffer(maHandle, 0, 0, barsNeeded, ma) < barsNeeded)
    {
        angleCalculationDetails = "数据不足，无法计算";
        return lastCalculatedAngle;
    }
    
    // 不使用ArraySetAsSeries，保持与指标一致的索引方式
    // 在CopyBuffer默认情况下：ma[0]=最旧，ma[barsNeeded-1]=最新
    int currentBar = barsNeeded - 1;  // 最新K线的索引
    
    // 按照指标的算法：ma[bar] - ma[bar-1] 表示 较新值 - 较旧值
    double angle1 = ma[currentBar] - ma[currentBar - 1];      // 最新变化
    double angle2 = ma[currentBar - 1] - ma[currentBar - 2];  // 第2新变化
    double angle3 = ma[currentBar - 2] - ma[currentBar - 3];  // 第3新变化
    double angle4 = ma[currentBar - 3] - ma[currentBar - 4];  // 第4新变化
    
    // 存储历史数据（最新5个MA值）
    for(int i = 0; i < 5; i++)
        maAngleHistory[i] = ma[currentBar - i];
    
    // 加权平均（与指标完全一致的权重）
    double avgAngle = angle1 * 0.4 + angle2 * 0.3 + angle3 * 0.2 + angle4 * 0.1;
    currentMAAngle = avgAngle;
    
    // 更新缓存
    lastCalculateTime = currentTime;
    lastCalculatedAngle = avgAngle;
    
    // 构建详细的计算详情字符串
    angleCalculationDetails = StringFormat(
        "MA值[新→旧]: %.5f→%.5f→%.5f→%.5f→%.5f\n" +
        "变化量: %.5f,%.5f,%.5f,%.5f\n" +
        "加权(40%%,30%%,20%%,10%%): %.5f\n" +
        "趋势: %s",
        maAngleHistory[0], maAngleHistory[1], maAngleHistory[2], maAngleHistory[3], maAngleHistory[4],
        angle1, angle2, angle3, angle4,
        avgAngle,
        (avgAngle > 0.0001 ? "上涨↗" : (avgAngle < -0.0001 ? "下跌↘" : "盘整→"))
    );
    
    // 减少调试输出频率 - 仅在每分钟输出一次
    static datetime lastDebugTime = 0;
    if(currentTime - lastDebugTime >= 60)
    {
        // Print("=== 均线角度计算详情 ===");
        // Print("MA[0-4]: ", ma[0], ",", ma[1], ",", ma[2], ",", ma[3], ",", ma[4]);
        // Print("角度变化: ", angle1, ",", angle2, ",", angle3, ",", angle4);
        // Print("加权结果: ", avgAngle, " (", (avgAngle > 0 ? "上涨" : "下跌"), ")");
        lastDebugTime = currentTime;
    }
    
    return avgAngle;
}

//+------------------------------------------------------------------+
//| 对亏损单按亏损比例排序（从大到小，即最负的在前）- 快速排序O(n log n) |
//+------------------------------------------------------------------+
void SortLossPositions(LossPositionInfo &lossPositions[], int count)
{
    if(count <= 1) return;
    QuickSortLossPositions(lossPositions, 0, count - 1);
}

//+------------------------------------------------------------------+
//| 优化版排序 - 使用全局预分配数组                                   |
//+------------------------------------------------------------------+
void SortLossPositionsOptimized(int count)
{
    if(count <= 1) return;
    QuickSortLossPositionsOptimized(0, count - 1);
}

//+------------------------------------------------------------------+
//| 快速排序实现 - O(n log n)复杂度                                   |
//+------------------------------------------------------------------+
void QuickSortLossPositions(LossPositionInfo &arr[], int low, int high)
{
    if(low < high)
    {
        int pivotIndex = PartitionLossPositions(arr, low, high);
        QuickSortLossPositions(arr, low, pivotIndex - 1);
        QuickSortLossPositions(arr, pivotIndex + 1, high);
    }
}

//+------------------------------------------------------------------+
//| 快速排序分区函数                                                  |
//+------------------------------------------------------------------+
int PartitionLossPositions(LossPositionInfo &arr[], int low, int high)
{
    double pivot = arr[high].lossPercent;
    int i = low - 1;
    
    for(int j = low; j < high; j++)
    {
        // 亏损比例更负的排在前面（小于pivot的放左边）
        if(arr[j].lossPercent < pivot)
        {
            i++;
            SwapLossPositions(arr, i, j);
        }
    }
    SwapLossPositions(arr, i + 1, high);
    return i + 1;
}

//+------------------------------------------------------------------+
//| 交换两个位置的数据                                                |
//+------------------------------------------------------------------+
void SwapLossPositions(LossPositionInfo &arr[], int i, int j)
{
    if(i == j) return;
    
    LossPositionInfo temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

//+------------------------------------------------------------------+
//| 优化版快速排序 - 使用全局数组                                     |
//+------------------------------------------------------------------+
void QuickSortLossPositionsOptimized(int low, int high)
{
    if(low < high)
    {
        int pivotIndex = PartitionLossPositionsOptimized(low, high);
        QuickSortLossPositionsOptimized(low, pivotIndex - 1);
        QuickSortLossPositionsOptimized(pivotIndex + 1, high);
    }
}

//+------------------------------------------------------------------+
//| 优化版分区函数 - 使用全局数组                                     |
//+------------------------------------------------------------------+
int PartitionLossPositionsOptimized(int low, int high)
{
    double pivot = globalLossPositions[high].lossPercent;
    int i = low - 1;
    
    for(int j = low; j < high; j++)
    {
        // 亏损比例更负的排在前面（小于pivot的放左边）
        if(globalLossPositions[j].lossPercent < pivot)
        {
            i++;
            SwapLossPositionsOptimized(i, j);
        }
    }
    SwapLossPositionsOptimized(i + 1, high);
    return i + 1;
}

//+------------------------------------------------------------------+
//| 优化版交换函数 - 使用全局数组                                     |
//+------------------------------------------------------------------+
void SwapLossPositionsOptimized(int i, int j)
{
    if(i == j) return;
    
    LossPositionInfo temp = globalLossPositions[i];
    globalLossPositions[i] = globalLossPositions[j];
    globalLossPositions[j] = temp;
}

//+------------------------------------------------------------------+
//| 执行选择性平仓                                                    |
//+------------------------------------------------------------------+
void ExecuteSelectiveClose(bool closeProfitBuy)
{
    Print("开始执行选择性平仓，closeProfitBuy=", closeProfitBuy);
    Print("平仓前持仓总数: ", PositionsTotal());
    
    // 先找出亏损方向的所有亏损单（在平掉盈利方向之前）
    LossPositionInfo lossPositions[];
    int lossCount = 0;
    
    // 统计亏损单数量
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                
                // 只检查亏损方向
                if((closeProfitBuy && posType == POSITION_TYPE_SELL) ||
                   (!closeProfitBuy && posType == POSITION_TYPE_BUY))
                {
                    double profit = PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
                    
                    Print("检查亏损方向持仓: 票号=", PositionGetTicket(i), 
                          ", 类型=", posType == POSITION_TYPE_BUY ? "BUY" : "SELL", 
                          ", 盈亏=", profit);
                    
                    // 只统计亏损的单子
                    if(profit < 0)
                    {
                        lossCount++;
                        Print("找到亏损单: 票号=", PositionGetTicket(i), ", 亏损=", profit);
                    }
                }
            }
        }
    }
    
    Print("亏损方向总共找到 ", lossCount, " 个亏损单");
    
    // 平掉盈利方向的所有持仓
    Print("开始平掉盈利方向持仓");
    ClosePositions(closeProfitBuy);
    
    // 执行阶段三反向顺势重置  
    // Phase3ReverseTrendReset(closeProfitBuy);
    
    if(lossCount > 0)
    {
        ArrayResize(lossPositions, lossCount + 5);  // 额外预留5个位置防止数组越界
        int index = 0;
        
        // 收集所有亏损单信息
        for(int i = 0; i < PositionsTotal(); i++)
        {
            if(PositionSelectByTicket(PositionGetTicket(i)))
            {
                if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
                   PositionGetInteger(POSITION_MAGIC) == Magic)
                {
                    ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                    
                    // 只检查亏损方向
                    if((closeProfitBuy && posType == POSITION_TYPE_SELL) ||
                       (!closeProfitBuy && posType == POSITION_TYPE_BUY))
                    {
                        double profit = PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
                        
                        if(profit < 0)
                        {
                            // 添加数组越界保护
                            if(index >= ArraySize(lossPositions))
                            {
                                Print("警告: ExecuteSelectiveClose数组空间不足，动态扩展数组大小");
                                ArrayResize(lossPositions, index + 10);
                            }
                            
                            double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                            double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
                            
                            // 计算亏损比例（相对于开仓价格的百分比，添加除零保护）
                            double lossPercent = 0;
                            if(openPrice > 0)  // 防止除零错误
                            {
                                if(posType == POSITION_TYPE_BUY)
                                {
                                    lossPercent = (currentPrice - openPrice) / openPrice * 100;  // 买单：现价低于开仓价时为负
                                }
                                else
                                {
                                    lossPercent = (openPrice - currentPrice) / openPrice * 100;  // 卖单：现价高于开仓价时为负
                                }
                            }
                            else
                            {
                                Print("警告: ExecuteSelectiveClose开仓价格为0，跳过此仓位");
                                continue;
                            }
                            
                            lossPositions[index].ticket = PositionGetTicket(i);
                            lossPositions[index].lossPercent = lossPercent;
                            lossPositions[index].lossAmount = profit;
                            index++;
                            
                            Print("收集亏损单信息: 票号=", PositionGetTicket(i), 
                                  ", 亏损比例=", lossPercent, "%, 亏损金额=", profit);
                        }
                    }
                }
            }
        }
        
        Print("实际收集到 ", index, " 个亏损单信息");
        
        if(index > 0)
        {
            // 对亏损单按亏损比例排序
            SortLossPositions(lossPositions, index);
            
            // 平掉前N个最大亏损单（使用原有固定逻辑）
            int closeCount = MathMin(Phase2SelectiveCloseMaxStopLossCount, index);
            Print("找到", index, "个亏损单，将平掉前", closeCount, "个最大亏损单");
            
            for(int i = 0; i < closeCount; i++)
            {
                MqlTradeRequest request = {};
                MqlTradeResult result = {};
                
                if(PositionSelectByTicket(lossPositions[i].ticket))
                {
                    request.action = TRADE_ACTION_DEAL;
                    request.symbol = Symbol();
                    request.volume = PositionGetDouble(POSITION_VOLUME);
                    request.type = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? 
                                  ORDER_TYPE_SELL : ORDER_TYPE_BUY;
                    request.price = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? 
                                   SymbolInfoDouble(Symbol(), SYMBOL_BID) : 
                                   SymbolInfoDouble(Symbol(), SYMBOL_ASK);
                    request.deviation = 10;
                    request.position = lossPositions[i].ticket;
                    request.type_filling = GetSupportedFillingMode();
                    request.magic = Magic;
                    
                    if(OrderSend(request, result))
                    {
                        Print("平掉第", (i+1), "个最大亏损单成功: 票号=", lossPositions[i].ticket, 
                              ", 亏损比例=", DoubleToString(MathAbs(lossPositions[i].lossPercent), 2), 
                              "%, 亏损金额=", lossPositions[i].lossAmount);
                    }
                    else
                    {
                        Print("平掉第", (i+1), "个最大亏损单失败: 票号=", lossPositions[i].ticket, 
                              ", 错误=", result.retcode, ", ", result.comment);
                    }
                }
                else
                {
                    Print("第", (i+1), "个最大亏损单已不存在: 票号=", lossPositions[i].ticket);
                }
            }
        }
    }
    
    // 执行阶段三平仓后重置（选择性平仓也触发）
    Phase3PostCloseReset();
    
    // 重置阶段二计数器，继续循环
    ResetPhase2Counters();
}

//+------------------------------------------------------------------+
//| 执行优化的选择性平仓                                              |
//+------------------------------------------------------------------+
void ExecuteOptimalSelectiveClose(bool isCloseBuy, int optimalStopCount, string calculationDetails)
{
    Print("========== 执行优化选择性平仓 ==========");
    Print("平仓方向: ", (isCloseBuy ? "平多头获利" : "平空头获利"));
    Print("最优止损单数: ", optimalStopCount);
    Print("计算详情: ", calculationDetails);
    
    ResetPhase2Counters();
    Print("========== 完成重置 ==========");
    Print("--- 第1步：执行最优止损策略 ---");
    ExecuteOptimalStopLoss(!isCloseBuy, optimalStopCount);     
    // 第1步：平掉盈利方向的所有持仓
    Print("--- 第2步：平掉盈利方向所有持仓 并开新的首单---"); 
    ClosePositions(isCloseBuy);
    
    Print("========== 优化选择性平仓完成 ==========");
}

//+------------------------------------------------------------------+
//| 执行最优止损（按亏损比例排序）                                    |
//+------------------------------------------------------------------+
void ExecuteOptimalStopLoss(bool stopBuy, int stopCount)
{
    Print("开始执行最优止损: 方向=", (stopBuy ? "多头" : "空头"), ", 数量=", stopCount);
    
    // 收集并排序亏损单
    LossPositionInfo lossPositions[];
    int lossCount = 0;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                double profit = PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
                
                bool isTargetDirection = (stopBuy && posType == POSITION_TYPE_BUY) || 
                                       (!stopBuy && posType == POSITION_TYPE_SELL);
                
                if(isTargetDirection && profit < 0)
                {
                    double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                    double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
                    double lossPercent = 0;
                    
                    if(openPrice > 0)  // 防止除零错误
                    {
                        if(posType == POSITION_TYPE_BUY)
                            lossPercent = (currentPrice - openPrice) / openPrice * 100;
                        else
                            lossPercent = (openPrice - currentPrice) / openPrice * 100;
                    }
                    else
                    {
                        Print("警告: ExecuteOptimalStopLoss开仓价格为0，跳过此仓位");
                        continue;
                    }
                    
                    ArrayResize(lossPositions, lossCount + 1);
                    lossPositions[lossCount].ticket = PositionGetTicket(i);
                    lossPositions[lossCount].lossPercent = lossPercent;
                    lossPositions[lossCount].lossAmount = profit;
                    lossCount++;
                }
            }
        }
    }
    
    if(lossCount == 0)
    {
        Print("未找到需要止损的单子");
        return;
    }
    
    // 排序
    SortLossPositions(lossPositions, lossCount);
    
    // 执行止损
    int actualStopCount = MathMin(stopCount, lossCount);
    double totalStopLossAmount = 0;
    int successCount = 0;
    
    Print("准备止损前", actualStopCount, "个亏损比例最大的单子:");
    
    for(int i = 0; i < actualStopCount; i++)
    {
        Print("止损[", i, "]: 票号=", lossPositions[i].ticket, 
              ", 亏损比例=", DoubleToString(lossPositions[i].lossPercent, 2), "%", 
              ", 亏损金额=", DoubleToString(lossPositions[i].lossAmount, 2));
        
        if(PositionSelectByTicket(lossPositions[i].ticket))
        {
            MqlTradeRequest request = {};
            MqlTradeResult result = {};
            
            request.action = TRADE_ACTION_DEAL;
            request.symbol = Symbol();
            request.volume = PositionGetDouble(POSITION_VOLUME);
            request.type = (stopBuy) ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
            request.price = (stopBuy) ? SymbolInfoDouble(Symbol(), SYMBOL_BID) : SymbolInfoDouble(Symbol(), SYMBOL_ASK);
            request.deviation = 10;
            request.position = lossPositions[i].ticket;
            request.type_filling = GetSupportedFillingMode();
            request.magic = Magic;
            
            if(OrderSend(request, result))
            {
                totalStopLossAmount += MathAbs(lossPositions[i].lossAmount);
                successCount++;
                Print("✓ 止损成功: 票号=", lossPositions[i].ticket);
            }
            else
            {
                Print("✗ 止损失败: 票号=", lossPositions[i].ticket, ", 错误=", result.retcode);
            }
        }
    }
    
    Print("止损执行完成: 计划", actualStopCount, "单, 成功", successCount, "单, 止损金额", DoubleToString(totalStopLossAmount, 2));
}

//+------------------------------------------------------------------+
//| 检查手数平衡                                                      |
//+------------------------------------------------------------------+
void CheckLotBalance()
{
    // 只在阶段二和阶段三执行手数平衡检查
    if(currentPhase != PHASE_TWO && currentPhase != PHASE_THREE)
        return;
        
    // 更新最新的持仓统计
    UpdatePositionStats();
    
    // 计算手数差异并标准化精度
    double lotDifference = NormalizeDouble(MathAbs(buyLots - sellLots), 2);
    
    // 输出调试信息（降低频率）
    static datetime lastDebugTime = 0;
    if(TimeCurrent() - lastDebugTime > 30)  // 每30秒输出一次
    {
        lastDebugTime = TimeCurrent();
    }
    
    // 检查是否超过平衡阈值（增加容差避免浮点数精度问题）
    double tolerance = 0.001;  // 容差
    if(lotDifference > Phase2LotBalanceThreshold + tolerance)
    {
        Print("检测到手数失衡: buyLots=", NormalizeDouble(buyLots, 2), 
              ", sellLots=", NormalizeDouble(sellLots, 2), 
              ", 差异=", lotDifference, ", 超过阈值=", Phase2LotBalanceThreshold);
        
        // 执行手数平衡操作
        ExecuteLotBalance();
    }
}

//+------------------------------------------------------------------+
//| 执行手数平衡操作                                                  |
//+------------------------------------------------------------------+
void ExecuteLotBalance()
{
    // 确定需要补仓的方向和手数
    bool needBuyMore = buyLots < sellLots;  // true表示需要补多单，false表示需要补空单
    double deficitLots = MathAbs(buyLots - sellLots);
    
    // 计算补仓手数：补仓数量 = 当前手数差 - 阀值
    double balanceLots = NormalizeDouble(deficitLots - Phase2LotBalanceThreshold, 2);
    
    // 安全处理：如果计算结果小于等于0，不执行平衡补仓
    if(balanceLots <= 0)
    {
        Print("安全检查：计算的补仓手数<=0 (", balanceLots, ")，跳过平衡补仓");
        return;
    }
    
    // 获取交易所最小手数限制
    double minLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
    
    // 检查是否低于交易所最小手数限制
    if(balanceLots < minLot)
    {
        Print("手数平衡：计算手数 ", balanceLots, " 低于交易所最小手数 ", minLot, "，调整为最小手数");
        balanceLots = minLot;
    }
    
    // 平衡补仓最大手数限制取消    
        
    Print("执行手数平衡: 需要补", needBuyMore ? "多单" : "空单", 
          ", 补仓手数=", balanceLots, ", 当前差额=", deficitLots, ", 阈值=", Phase2LotBalanceThreshold);
    
    // 执行平衡补仓
    MqlTradeRequest request = {};
    MqlTradeResult result = {};
    
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    
    request.action = TRADE_ACTION_DEAL;
    request.symbol = Symbol();
    request.volume = balanceLots;
    request.deviation = 10;
    request.type_filling = GetSupportedFillingMode();
    request.magic = Magic;
    
    if(needBuyMore)
    {
        // 补多单
        request.type = ORDER_TYPE_BUY;
        request.price = ask;
        
        string phaseStr = (currentPhase == PHASE_TWO) ? "阶段2_" : "阶段3_";
        request.comment = phaseStr + "多头平衡补仓";
        
        if(OrderSend(request, result))
        {
            Print("多头平衡补仓成功: 手数=", balanceLots, ", 价格=", ask);
            
            // 更新最后买入价格
            lastBuyPrice = ask;
            lastBuyTime = TimeCurrent();
            
            // 立即强制刷新持仓统计，避免连续平衡补仓
            UpdatePositionStats(true);
        }
        else
        {
            Print("多头平衡补仓失败: ", result.retcode, ", ", result.comment);
        }
    }
    else
    {
        // 补空单
        request.type = ORDER_TYPE_SELL;
        request.price = bid;
        
        string phaseStr = (currentPhase == PHASE_TWO) ? "阶段2_" : "阶段3_";
        request.comment = phaseStr + "空头平衡补仓";
        
        if(OrderSend(request, result))
        {
            Print("空头平衡补仓成功: 手数=", balanceLots, ", 价格=", bid);
            
            // 更新最后卖出价格
            lastSellPrice = bid;
            lastSellTime = TimeCurrent();
            
            // 立即强制刷新持仓统计，避免连续平衡补仓
            UpdatePositionStats(true);
        }
        else
        {
            Print("空头平衡补仓失败: ", result.retcode, ", ", result.comment);
        }
    }
}

//+------------------------------------------------------------------+
//| 图表事件处理函数                                                  |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
    // 处理键盘事件
    if(id == CHARTEVENT_KEYDOWN)
    {
        // 按空格键切换面板显示
        if(lparam == 32) // 空格键
        {
            // 只在启用面板显示参数时才允许切换
            if(ShowMonitorPanel)
            {
                showPanel = !showPanel;
                if(!showPanel)
                {
                    // 隐藏面板时删除所有对象
                    DeletePanelObjects();
                }
                ChartRedraw();
            }
        }
    }
    
    // 处理鼠标点击事件
    if(id == CHARTEVENT_OBJECT_CLICK)
    {
        if(StringFind(sparam, "PanelButton") >= 0)
        {
            // 处理面板按钮点击
            HandlePanelButtonClick(sparam);
        }
    }
}

//+------------------------------------------------------------------+
//| 绘制监控面板                                                      |
//+------------------------------------------------------------------+
void DrawMonitoringPanel()
{
    if(!showPanel || !ShowMonitorPanel) return;  // 检查全局参数和局部状态
    
    // 删除旧的面板对象
    DeletePanelObjects();
    
    // 计算实际面板位置（应用偏移量）
    int actualPanelX = panelX + PanelXOffset;
    int actualPanelY = panelY + PanelYOffset;
    
    // 绘制面板背景
    string panelName = "MonitorPanel";
    if(!ObjectCreate(0, panelName, OBJ_RECTANGLE_LABEL, 0, 0, 0))
        ObjectDelete(0, panelName);
    if(ObjectCreate(0, panelName, OBJ_RECTANGLE_LABEL, 0, 0, 0))
    {
        ObjectSetInteger(0, panelName, OBJPROP_XDISTANCE, actualPanelX);
        ObjectSetInteger(0, panelName, OBJPROP_YDISTANCE, actualPanelY);
        ObjectSetInteger(0, panelName, OBJPROP_XSIZE, panelWidth);
        ObjectSetInteger(0, panelName, OBJPROP_YSIZE, panelHeight);
        ObjectSetInteger(0, panelName, OBJPROP_BGCOLOR, panelBgColor);
        ObjectSetInteger(0, panelName, OBJPROP_BORDER_COLOR, panelBorderColor);
        ObjectSetInteger(0, panelName, OBJPROP_BORDER_TYPE, BORDER_FLAT);
        ObjectSetInteger(0, panelName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
        ObjectSetInteger(0, panelName, OBJPROP_BACK, false);
        ObjectSetInteger(0, panelName, OBJPROP_SELECTABLE, false);
        ObjectSetInteger(0, panelName, OBJPROP_HIDDEN, true);
    }
    
    // 绘制标题
    DrawPanelText("PanelTitle", "智能对冲交易系统", actualPanelX + 10, actualPanelY + 10, clrGold, 12);
    // DrawPanelText("PanelHint", "按空格键切换显示/隐藏", actualPanelX + 10, actualPanelY + 30, clrLightGray, 8);
    
    int yPos = actualPanelY + 55;
    
    // 当前阶段信息
    string phaseStr = "";
    color phaseColor = clrWhite;
    switch(currentPhase)
    {
        case PHASE_ONE: 
            phaseStr = "智能建仓模式"; 
            phaseColor = clrAquamarine;
            break;
        case PHASE_TWO: 
            phaseStr = "动态对冲模式"; 
            phaseColor = clrLime;
            break;
        case PHASE_THREE: 
            phaseStr = "高级风控模式"; 
            phaseColor = clrOrange;
            break;
    }
    DrawPanelText("CurrentPhase", "当前阶段: " + phaseStr, actualPanelX + 10, yPos, phaseColor, 10);
    yPos += 25;
    
    // 暂停状态
    if(isPaused)
    {
        DrawPanelText("PauseStatus", "状态: 已暂停 (剩余: " + 
                     IntegerToString((int)((pauseEndTime - TimeCurrent()) / 60)) + "分钟)", 
                     actualPanelX + 10, yPos, clrRed, 9);
    }
    else
    {
        DrawPanelText("PauseStatus", "状态: 运行中", actualPanelX + 10, yPos, clrLightGreen, 9);
    }
    yPos += 25;
    
    // 均线信息
    if(ShowMAInPanel)
    {
        DrawPanelText("MATitle", "═══ 趋势分析 ═══", actualPanelX + 10, yPos, clrGold, 10);
        yPos += 20;
    }
    
    // 获取均线数据
    double maValues[3];
    if(ShowMAInPanel && CopyBuffer(maHandle, 0, 0, 3, maValues) >= 3)
    {
        double maAngle = CalculateMAAngle();
        
        // 当前MA值
        string maValueStr = StringFormat("MA(%d): %.5f", MAPeriod, maValues[0]);
        DrawPanelText("MAValue", maValueStr, actualPanelX + 15, yPos, clrWhite, 9);
        yPos += 18;
        
        // 均线角度
        string angleStr = StringFormat("角度: %.5f", maAngle);
        color angleColor = clrYellow;
        if(maAngle > MAAngleThreshold) angleColor = clrLime;
        else if(maAngle < -MAAngleThreshold) angleColor = clrRed;
        DrawPanelText("MAAngle", angleStr, actualPanelX + 15, yPos, angleColor, 9);
        yPos += 18;
        
        // 趋势方向
        string trendStr = "趋势: ";
        if(maAngle > MAAngleThreshold) trendStr += "上涨 ↗";
        else if(maAngle < -MAAngleThreshold) trendStr += "下跌 ↘";
        else trendStr += "盘整 →";
        DrawPanelText("MATrend", trendStr, actualPanelX + 15, yPos, angleColor, 9);
        yPos += 18;
        
        // === 详细角度计算调试信息 ===
        //DrawPanelText("MADebugTitle", "--- 角度计算调试 ---", actualPanelX + 15, yPos, clrCyan, 8);
         //yPos += 15;
        
        // 显示5个MA值（从新到旧）
          //DrawPanelText("MAValues1", StringFormat("MA[新→旧]: %.5f→%.5f→%.5f",
           //            maAngleHistory[0], maAngleHistory[1], maAngleHistory[2]),
             //          actualPanelX + 20, yPos, clrLightGreen, 7);
          //yPos += 12;
        
          //DrawPanelText("MAValues2", StringFormat("           →%.5f→%.5f",
            //           maAngleHistory[3], maAngleHistory[4]),
           //            actualPanelX + 20, yPos, clrLightGreen, 7);
          //yPos += 12;
        
        // 显示4个角度变化
          //double angle1 = maAngleHistory[0] - maAngleHistory[1];
          //double angle2 = maAngleHistory[1] - maAngleHistory[2];
          //double angle3 = maAngleHistory[2] - maAngleHistory[3];
          //double angle4 = maAngleHistory[3] - maAngleHistory[4];
        
        // DrawPanelText("AngleChanges1", StringFormat("变化: %.5f, %.5f", angle1, angle2), 
        //              actualPanelX + 20, yPos, clrWhite, 7);
        // yPos += 12;
        
        // DrawPanelText("AngleChanges2", StringFormat("      %.5f, %.5f", angle3, angle4), 
        //              actualPanelX + 20, yPos, clrWhite, 7);
        // yPos += 12;
        
        // 显示加权计算
        // DrawPanelText("WeightCalc1", StringFormat("加权: %.5f×0.4 + %.5f×0.3", angle1, angle2), 
        //              actualPanelX + 20, yPos, clrYellow, 7);
        // yPos += 12;
        
        // DrawPanelText("WeightCalc2", StringFormat("    + %.5f×0.2 + %.5f×0.1", angle3, angle4), 
        //              actualPanelX + 20, yPos, clrYellow, 7);
        // yPos += 12;
        
        // // 最终结果验证
        // double calcResult = angle1*0.4 + angle2*0.3 + angle3*0.2 + angle4*0.1;
        // DrawPanelText("FinalResult", StringFormat("结果: %.5f (%s)", calcResult, 
        //              (calcResult > 0 ? "正值=上涨" : "负值=下跌")), 
        //              actualPanelX + 20, yPos, (calcResult > 0 ? clrLime : clrRed), 8);
        // yPos += 15;
    }
    else if(ShowMAInPanel)
    {
        DrawPanelText("MAError", "均线数据获取失败", actualPanelX + 15, yPos, clrRed, 9);
        yPos += 18;
        yPos += 10; // 额外间距
    }
    
    // 持仓统计
    DrawPanelText("PositionTitle", "═══ 持仓统计 ═══", actualPanelX + 10, yPos, clrGold, 10);
    yPos += 20;
    
    // 多头持仓
    string buyInfo = StringFormat("多头: %d单 %.2f手", buyPositions, buyLots);
    color buyColor = buyPositions > 0 ? clrLightGreen : clrGray;
    DrawPanelText("BuyPositions", buyInfo, actualPanelX + 15, yPos, buyColor, 9);
    yPos += 18;
    
    if(buyPositions > 0)
    {
        DrawPanelText("BuyRange", StringFormat("  价格区间: %.5f - %.5f", minBuyPrice, maxBuyPrice), 
                     actualPanelX + 15, yPos, clrLightBlue, 8);
        yPos += 15;
    }
    
    // 空头持仓
    string sellInfo = StringFormat("空头: %d单 %.2f手", sellPositions, sellLots);
    color sellColor = sellPositions > 0 ? clrLightCoral : clrGray;
    DrawPanelText("SellPositions", sellInfo, actualPanelX + 15, yPos, sellColor, 9);
    yPos += 18;
    
    if(sellPositions > 0)
    {
        DrawPanelText("SellRange", StringFormat("  价格区间: %.5f - %.5f", minSellPrice, maxSellPrice), 
                     actualPanelX + 15, yPos, clrLightCoral, 8);
        yPos += 15;
    }
    
    // 盈亏统计
    DrawPanelText("ProfitTitle", "═══ 盈亏统计 ═══", actualPanelX + 10, yPos, clrGold, 10);
    yPos += 20;
    
    // 计算总盈亏
    double totalProfit = 0;
    double buyProfit = 0;
    double sellProfit = 0;
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                double profit = PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
                totalProfit += profit;
                
                if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                    buyProfit += profit;
                else
                    sellProfit += profit;
            }
        }
    }
    
    // 总盈亏
    color totalColor = totalProfit >= 0 ? clrLightGreen : clrLightCoral;
    DrawPanelText("TotalProfit", StringFormat("总盈亏: $%.2f", totalProfit), 
                 actualPanelX + 15, yPos, totalColor, 9);
    yPos += 18;
    
    // 多头盈亏
    color buyProfitColor = buyProfit >= 0 ? clrLightGreen : clrLightCoral;
    DrawPanelText("BuyProfit", StringFormat("多头盈亏: $%.2f", buyProfit), 
                 actualPanelX + 15, yPos, buyProfitColor, 8);
    yPos += 15;
    
    // 空头盈亏
    color sellProfitColor = sellProfit >= 0 ? clrLightGreen : clrLightCoral;
    DrawPanelText("SellProfit", StringFormat("空头盈亏: $%.2f", sellProfit), 
                 actualPanelX + 15, yPos, sellProfitColor, 8);
    yPos += 20;
    
    // 阶段特定信息
    if(currentPhase == PHASE_ONE)
    {
        DrawPanelText("PhaseInfo", "═══ 智能建仓信息 ═══", actualPanelX + 10, yPos, clrGold, 10);
        yPos += 20;
        
        DrawPanelText("ResetCount", StringFormat("重置参数: %d (0=禁用)", ResetOrderCount), 
                     actualPanelX + 15, yPos, clrLightBlue, 8);
        yPos += 15;
        
        DrawPanelText("UseStep", StringFormat("参数模式: %s", UseSetp ? "第一套" : "第二套"), 
                     actualPanelX + 15, yPos, clrLightBlue, 8);
        yPos += 15;
        
        // 挂单信息
        int buyPendingCount = GetBuyStopCount();
        int sellPendingCount = GetSellStopCount();
        DrawPanelText("PendingOrders", StringFormat("挂单: 多%d 空%d", buyPendingCount, sellPendingCount), 
                     actualPanelX + 15, yPos, clrLightGray, 8);
        yPos += 15;
    }
    else if(currentPhase >= PHASE_TWO)
    {
        DrawPanelText("PhaseInfo", "═══ 对冲策略信息 ═══", actualPanelX + 10, yPos, clrGold, 10);
        yPos += 20;
        
        DrawPanelText("BuyTrend", StringFormat("多头: 顺势%d 逆势%d", phase2BuyTrendCount, phase2BuyAntiCount), 
                     actualPanelX + 15, yPos, clrLightGreen, 8);
        yPos += 15;
        
        DrawPanelText("SellTrend", StringFormat("空头: 顺势%d 逆势%d", phase2SellTrendCount, phase2SellAntiCount), 
                     actualPanelX + 15, yPos, clrLightCoral, 8);
        yPos += 15;
        
        DrawPanelText("ProfitTarget", StringFormat("目标: 整体$%.1f 选择$%.1f", Phase2ProfitTarget, Phase2SelectiveProfitTarget), 
                     actualPanelX + 15, yPos, clrLightBlue, 8);
        yPos += 15;
        
        // 加仓判断模式
        DrawPanelText("AddPositionMode", StringFormat("加仓判断: %s", Phase2UseClosePrice ? "收盘价" : "实时价格"), 
                     actualPanelX + 15, yPos, Phase2UseClosePrice ? clrLightGreen : clrOrange, 8);
        yPos += 15;
        
        // 如果使用收盘价，显示上一根收盘价
        if(Phase2UseClosePrice)
        {
            double lastClose = iClose(Symbol(), PERIOD_CURRENT, 1);
            if(lastClose > 0)
            {
                DrawPanelText("LastClosePrice", StringFormat("上根收盘: %.5f", lastClose), 
                             actualPanelX + 20, yPos, clrLightGray, 7);
                yPos += 12;
            }
        }
        
        // 优化设置显示
        DrawPanelText("OptimizationTitle", "═══ 智能优化 ═══", 
                     actualPanelX + 10, yPos, clrGold, 9);
        yPos += 15;
        
        DrawPanelText("MaxStopCount", StringFormat("最大止损单数: %d", Phase2SelectiveCloseMaxStopLossCount), 
                     actualPanelX + 20, yPos, clrWhite, 7);
        yPos += 12;
        
        DrawPanelText("OptimalEnabled", StringFormat("优化计算: %s", EnableOptimalStopLossCalculation ? "启用" : "禁用"), 
                     actualPanelX + 20, yPos, EnableOptimalStopLossCalculation ? clrLightGreen : clrGray, 7);
        yPos += 12;
        
        // 选择性平仓状态
        color selectiveColor = clrLightGray;
        if(selectiveCloseEnabled)
        {
            if(StringFind(selectiveCloseStatus, "执行平仓") >= 0) selectiveColor = clrLime;
            else if(StringFind(selectiveCloseStatus, "净盈利不足") >= 0) selectiveColor = clrOrange;
            else selectiveColor = clrYellow;
        }
        else
        {
            if(StringFind(selectiveCloseStatus, "趋势不符") >= 0) selectiveColor = clrCoral;
            else if(StringFind(selectiveCloseStatus, "无盈亏分化") >= 0) selectiveColor = clrGray;
        }
        
        DrawPanelText("SelectiveStatus", StringFormat("选择性平仓: %s", selectiveCloseStatus), 
                     actualPanelX + 15, yPos, selectiveColor, 8);
        yPos += 15;
        
        // 选择性平仓条件详情
        if(selectiveCloseEnabled && selectiveCloseCondition != "")
        {
            DrawPanelText("SelectiveCondition", StringFormat("条件: %s", selectiveCloseCondition), 
                         actualPanelX + 15, yPos, clrLightBlue, 8);
            yPos += 15;
            
            DrawPanelText("SelectiveNetProfit", StringFormat("净盈利: $%.2f (目标$%.1f)", selectiveNetProfit, Phase2SelectiveProfitTarget), 
                         actualPanelX + 15, yPos, selectiveNetProfit >= Phase2SelectiveProfitTarget ? clrLime : clrOrange, 8);
            yPos += 15;
        }
        
        // 手数平衡
        double lotDiff = MathAbs(buyLots - sellLots);
        color balanceColor = lotDiff <= Phase2LotBalanceThreshold ? clrLightGreen : clrOrange;
        DrawPanelText("LotBalance", StringFormat("手数差: %.2f (阈值%.2f)", lotDiff, Phase2LotBalanceThreshold), 
                     actualPanelX + 15, yPos, balanceColor, 8);
        yPos += 15;
    }
    
    // 风控信息
    DrawPanelText("RiskTitle", "═══ 风控信息 ═══", actualPanelX + 10, yPos, clrGold, 10);
    yPos += 20;
    
    if(EnableGlobalRiskControl)
    {
        double lossPercent = (totalProfit / -MaxAccountLoss) * 100;
        color riskColor = clrLightGreen;
        if(lossPercent > 80) riskColor = clrRed;
        else if(lossPercent > 50) riskColor = clrOrange;
        
        DrawPanelText("RiskControl", StringFormat("亏损占比: %.1f%% (%.0f/%.0f)", 
                     lossPercent, -totalProfit, MaxAccountLoss), 
                     actualPanelX + 15, yPos, riskColor, 8);
        yPos += 15;
    }
    else
    {
        DrawPanelText("RiskControl", "全局风控: 已禁用", actualPanelX + 15, yPos, clrGray, 8);
        yPos += 15;
    }
    
    // 当前价格和点差
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    double spread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);
    
    DrawPanelText("Prices", StringFormat("买价: %.5f 卖价: %.5f", ask, bid), 
                 actualPanelX + 15, yPos, clrLightGray, 8);
    yPos += 15;
    
    color spreadColor = spread <= MaxSpread ? clrLightGreen : clrRed;
    DrawPanelText("Spread", StringFormat("点差: %.0f (限制%d)", spread, MaxSpread), 
                 actualPanelX + 15, yPos, spreadColor, 8);
    yPos += 20;
    
    // 版本信息
    DrawPanelText("Version", "V2.0 Professional", actualPanelX + 10, yPos, clrDimGray, 7);
    yPos += 12;
    DrawPanelText("Hint", "按空格键隐藏/显示", actualPanelX + 10, yPos, clrDimGray, 7);
}

//+------------------------------------------------------------------+
//| 绘制面板文字                                                      |
//+------------------------------------------------------------------+
void DrawPanelText(string name, string text, int x, int y, color textColor, int fontSize)
{
    string objName = "Panel_" + name;
    
    if(!ObjectCreate(0, objName, OBJ_LABEL, 0, 0, 0))
        ObjectDelete(0, objName);
    if(ObjectCreate(0, objName, OBJ_LABEL, 0, 0, 0))
    {
        ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, x);
        ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, y);
        ObjectSetString(0, objName, OBJPROP_TEXT, text);
        ObjectSetInteger(0, objName, OBJPROP_COLOR, textColor);
        ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize);
        ObjectSetString(0, objName, OBJPROP_FONT, "Arial");  // 改为Arial字体，更美观
        ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
        ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false);
        ObjectSetInteger(0, objName, OBJPROP_HIDDEN, true);
    }
}

//+------------------------------------------------------------------+
//| 删除面板对象                                                      |
//+------------------------------------------------------------------+
void DeletePanelObjects()
{
    // 删除所有面板相关对象
    ObjectDelete(0, "MonitorPanel");
    
    string objList[] = {
        "Panel_PanelTitle", "Panel_PanelHint", "Panel_CurrentPhase", "Panel_PauseStatus",
        "Panel_PositionTitle", "Panel_BuyPositions", "Panel_BuyRange", "Panel_SellPositions", "Panel_SellRange",
        "Panel_ProfitTitle", "Panel_TotalProfit", "Panel_BuyProfit", "Panel_SellProfit",
        "Panel_PhaseInfo", "Panel_ResetCount", "Panel_UseStep", "Panel_PendingOrders",
        "Panel_BuyTrend", "Panel_SellTrend", "Panel_ProfitTarget", "Panel_MAAngle", "Panel_LotBalance",
        "Panel_SelectiveStatus", "Panel_SelectiveCondition", "Panel_SelectiveNetProfit",
        "Panel_RiskTitle", "Panel_RiskControl", "Panel_Prices", "Panel_Spread",
        "Panel_MADetails", "Panel_MAParams", "Panel_MAValues1", "Panel_MAValues2",
        "Panel_AngleDiffs1", "Panel_AngleDiffs2", "Panel_WeightCalc", "Panel_WeightCalc2",
        "Panel_WeightResult", "Panel_MAError", "Panel_OptimizationTitle", "Panel_MaxStopCount", "Panel_OptimalEnabled",
        "Panel_MADebugTitle", "Panel_AngleChanges1", "Panel_AngleChanges2", 
        "Panel_WeightCalc1", "Panel_FinalResult", "Panel_MATitle", "Panel_MAValue", "Panel_MATrend",
        "Panel_AddPositionMode", "Panel_LastClosePrice", "Panel_Version", "Panel_Hint"
    };
    
    for(int i = 0; i < ArraySize(objList); i++)
    {
        ObjectDelete(0, objList[i]);
    }
}

//+------------------------------------------------------------------+
//| 绘制均线到图表                                                    |
//+------------------------------------------------------------------+
// 均线绘制函数已删除以避免栈溢出
/*
void DrawMALineOnChart()
{
    // 此函数已被删除以避免实盘栈溢出问题
    // 原因：高频Tick环境下创建大量图形对象导致内存栈耗尽
    return;
}
*/

//+------------------------------------------------------------------+
//| 手动绘制均线（当自动添加失败时使用）                              |
//+------------------------------------------------------------------+
// 手动绘制均线函数已删除
/*
void DrawCustomMALine()
{
    // 此函数已被删除以避免实盘栈溢出问题
    return;
}
*/

//+------------------------------------------------------------------+
//| 绘制均线趋势箭头指示器                                            |
//+------------------------------------------------------------------+
// 均线趋势箭头函数已删除
/*
void DrawMATrendArrow(double maAngle, double maValue)
{
    // 此函数已被删除以避免实盘栈溢出问题
    return;
}
*/

//+------------------------------------------------------------------+
//| 删除均线对象                                                      |
//+------------------------------------------------------------------+
// 删除均线对象函数已删除
/*
void DeleteMALineObjects()
{
    // 此函数已被删除，均线绘制功能已移除
    return;
}
*/

//+------------------------------------------------------------------+
//| 处理面板按钮点击                                                  |
//+------------------------------------------------------------------+
void HandlePanelButtonClick(string buttonName)
{
    // 预留给未来的按钮功能扩展
    Print("面板按钮被点击: " + buttonName);
}

//+------------------------------------------------------------------+
//| EA状态恢复功能（重新加载后自动判断应该处于哪个阶段）                   |
//+------------------------------------------------------------------+
void RecoverEAState()
{
    Print("=== 开始EA状态恢复检查 ===");
    
    // 检查是否有阶段二/三相关的持仓（通过订单注释判断）
    bool hasPhase2Positions = false;
    bool hasPhase3Positions = false;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByTicket(PositionGetTicket(i)))
        {
            if(PositionGetString(POSITION_SYMBOL) == Symbol() && 
               PositionGetInteger(POSITION_MAGIC) == Magic)
            {
                string comment = PositionGetString(POSITION_COMMENT);
                
                if(StringFind(comment, "阶段2_") >= 0)
                {
                    hasPhase2Positions = true;
                }
                if(StringFind(comment, "阶段3_") >= 0)
                {
                    hasPhase3Positions = true;
                }
            }
        }
    }
    
    // 根据持仓情况恢复阶段
    if(hasPhase3Positions)
    {
        currentPhase = PHASE_THREE;
        Print("检测到阶段三持仓，恢复到阶段三");
        // 重新初始化阶段三计数器（需要根据实际持仓重新计算）
        InitializePhase2Counters();
    }
    else if(hasPhase2Positions)
    {
        currentPhase = PHASE_TWO;
        Print("检测到阶段二持仓，恢复到阶段二");
        // 重新初始化阶段二计数器
        InitializePhase2Counters();
    }
    else if(buyPositions > 0 || sellPositions > 0)
    {
        // 有持仓但没有阶段二/三标记，可能是阶段一的持仓
        Print("检测到持仓但无阶段标记，判断应处于的阶段...");
        
        // 检查ResetOrderCount设置和持仓数量
        if(ResetOrderCount == 0)
        {
            // ResetOrderCount=0时，有持仓就应该是阶段二
            currentPhase = PHASE_TWO;
            Print("ResetOrderCount=0且有持仓，恢复到阶段二");
            InitializePhase2Counters();
        }
        else
        {
            // 检查是否满足升级条件
            bool shouldUpgrade = false;
            
            // 检查订单数量条件
            if(buyOrderCount >= ResetOrderCount || sellOrderCount >= ResetOrderCount)
            {
                // 还需要检查价格距离条件，但重新加载后可能无法准确判断
                // 为了安全，如果持仓数量已经达到ResetOrderCount，直接升级到阶段二
                shouldUpgrade = true;
            }
            
            if(shouldUpgrade)
            {
                currentPhase = PHASE_TWO;
                Print("持仓数量达到升级条件，恢复到阶段二");
                DeleteAllPendingOrders(); // 清理可能存在的阶段一挂单
                InitializePhase2Counters();
            }
            else
            {
                // 保持阶段一，但需要清理和重建挂单状态
                currentPhase = PHASE_ONE;
                Print("持仓数量未达到升级条件，保持阶段一");
                RecoverPhase1PendingOrders();
            }
        }
    }
    else
    {
        // 没有持仓，保持阶段一，但可能有旧挂单需要处理
        currentPhase = PHASE_ONE;
        Print("无持仓，保持阶段一");
        RecoverPhase1PendingOrders();
    }
    
    // 输出恢复结果
    Print("状态恢复完成: 当前阶段=", EnumToString(currentPhase));
    Print("持仓状态: 买单=", buyPositions, ", 卖单=", sellPositions);
    Print("价格范围: minBuyPrice=", minBuyPrice, ", maxBuyPrice=", maxBuyPrice);
    Print("=== EA状态恢复检查完成 ===");
}

//+------------------------------------------------------------------+
//| 初始化阶段二计数器（根据现有持仓重新计算）                          |
//+------------------------------------------------------------------+
void InitializePhase2Counters()
{
    Print("开始初始化阶段二计数器...");
    
    // 重置所有计数器
    phase2BuyTrendCount = 0;
    phase2BuyAntiCount = 0;
    phase2SellTrendCount = 0;
    phase2SellAntiCount = 0;
    
    // 如果有持仓，设置基础计数器
    if(buyPositions > 0)
    {
        phase2BuyTrendCount = 1;
        phase2BuyAntiCount = 1;
        Print("初始化买单计数器: phase2BuyTrendCount=1, phase2BuyAntiCount=1");
    }
    
    if(sellPositions > 0)
    {
        phase2SellTrendCount = 1;
        phase2SellAntiCount = 1;
        Print("初始化卖单计数器: phase2SellTrendCount=1, phase2SellAntiCount=1");
    }
    
    Print("阶段二计数器初始化完成");
}

//+------------------------------------------------------------------+
//| 恢复阶段一挂单状态                                               |
//+------------------------------------------------------------------+
void RecoverPhase1PendingOrders()
{
    Print("=== 开始阶段一挂单状态恢复 ===");
    
    // 统计现有挂单
    int existingBuyStops = 0;
    int existingSellStops = 0;
    
    for(int i = 0; i < OrdersTotal(); i++)
    {
        if(OrderSelect(OrderGetTicket(i)))
        {
            if(OrderGetString(ORDER_SYMBOL) == Symbol() && 
               OrderGetInteger(ORDER_MAGIC) == Magic)
            {
                ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
                double orderPrice = OrderGetDouble(ORDER_PRICE_OPEN);
                
                if(orderType == ORDER_TYPE_BUY_STOP)
                {
                    existingBuyStops++;
                    Print("检测到买入挂单: 票号=", OrderGetTicket(i), ", 价格=", orderPrice);
                }
                else if(orderType == ORDER_TYPE_SELL_STOP)
                {
                    existingSellStops++;
                    Print("检测到卖出挂单: 票号=", OrderGetTicket(i), ", 价格=", orderPrice);
                }
            }
        }
    }
    
    Print("现有挂单统计: 买入挂单=", existingBuyStops, ", 卖出挂单=", existingSellStops);
    
    // 策略决策：为确保价格逻辑正确，清理所有旧挂单并重新创建
    if(existingBuyStops > 0 || existingSellStops > 0)
    {
        Print("检测到旧挂单，为确保价格逻辑正确，将清理所有旧挂单");
        Print("原因: 重新加载EA后，旧挂单价格可能不符合当前市场价格和参数设置");
        
        // 删除所有挂单
        DeleteAllPendingOrders();
        
        // 重置挂单追踪变量
        buyPendingTicket = 0;
        sellPendingTicket = 0;
        lastBuyPendingPrice = 0.0;
        lastSellPendingPrice = 0.0;
        
        Print("旧挂单清理完成，后续将根据当前市场价格重新创建合适的挂单");
    }
    else
    {
        Print("未检测到旧挂单，挂单状态正常");
        
        // 确保追踪变量重置
        buyPendingTicket = 0;
        sellPendingTicket = 0;
        lastBuyPendingPrice = 0.0;
        lastSellPendingPrice = 0.0;
    }
    
    Print("=== 阶段一挂单状态恢复完成 ===");
}